Print and store spanish characters (á, é, í, ñ...) in cmd

Viewed 654

I'm using Microsoft Windows 10 with mingw-w64 (gcc version 8.1.0, x86_64-posix-sjlj-rev0, Built by MinGW-W64 project) with cmd. When I try to print or store and then print a Spanish character on the Windows console, it shows an error. For example I tried to execute this program:

#include <stdio.h>

int main(void) {
    char c[20];
    printf("pía\n");
    scanf("%s", c);
    printf("%s", c);
}

If I introduce some Spanish characters the returned sentence is OK but the printed one at the beginning shows an error:

pía
laíóñaú
laíóñaú

Some solutions suggest putting setlocale() function but the results are the same. Other solution is put the UTF-8 unicode compatibility on region settings:

enter image description here

But now the error is the opposite, the printed one is OK but when I introduce a strange character the console doesn't show it:

pía
lía
l

It is a bit frustrating since all the solutions I have seen are solved with the above or by setting setlocale(), but none of them work for me and I don't know why.

EDIT

As Mofi say in comments I try to use SetConsoleCP() and SetConsoleOutputCP() to change the code page of the console. Without fully understanding how these functions work, with the same code as above, I ran several examples with wrong results:

pía                       | p├¡a                    | p├¡a                  | pía
lía                       | lía                     | lía                   | lía
l                         | l                       | lía                   | la
input: 65001 output 65001 | input: 65001 output 850 | input: 850 output 850 | input: 850 output 65001

How I don't fully understand this functions I don't know why in the last example, the console don't show the accented stored character but in the printed one it does and in the example above the opposite happens.

2 Answers

I played around with this for a while and the only thing that worked was using _setmode() to set the stdin and stdout to take in wide characters, and then working with wchar_t instead of char to store the text. This code works as intended on my machine:

#include <stdio.h>
#include <fcntl.h>
#include <io.h>

int main(void) {
    _setmode(_fileno(stdin), _O_WTEXT);
    _setmode(_fileno(stdout), _O_WTEXT);
    wchar_t c[20];
    wprintf(L"pía\n");
    wscanf(L"%ls", c);
    wprintf(L"%ls", c);
}

EDITED: I changed the parameter of _setmode from _O_U16TEXT to _O_WTEXT to avoid implementation issues resulting from how the length of wchar_t is either 2 or 4 bytes based on the compiler.

As Mofi said in comments above, the solution comes in how the editor that I was using interpret the character that I wrote. I was using Visual Studio Code and to change the encoding that comes by default, in the lower right corner change UTF-8to CP 850. Now the editor will be able to correctly interpret Spanish character.

The next problem is change the code page of the console. With the command chcp 850 or with the functions SetConsoleCP(850) and SetConsoleOutputCP(850) we can change the code page on every console that we open. To set this by default do the folowing:

  • Open the Registry Editor and go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor.
  • New -> String Valueand put the name Autorun.
  • Modify the value to chcp 850 > nul.
Related