Search code examples
cutf-8mingw-w64wine

Build a program with mingw on linux and run under wine --- UTF-8 support


I have C code that prints some characters. I would like to see these characters printed, as opposed to an alphabet soup,

#include <stdio.h>
int main() {
    const char* test = "Greek: αβγδ; German: Übergrößenträger";
    printf("%s\n", test);
}

What works:

  1. Native Linux compilation: gcc test.c -o test && ./test
  2. Winegcc compilation: winegcc test.c o test.exe && ./test.exe
  3. MinGW64 compilation when the output is not a terminal : x86_64-w64-mingw32-gcc -o test.exe test.cpp && wine ./test.exe | cat

All three commands print Greek: αβγδ; German: Übergrößenträger to the terminal.

What doesn't work:

  1. MinGW64 compilation when the output is a terminal: x86_64-w64-mingw32-gcc -o test.exe test.cpp && wine ./test.exe

This prints Greek: αβγδ; German: ÃbergröÃenträger to the terminal.

It looks like the MinGW runtime detects if the output is a terminal/console, and does exactly the wrong thing.

What I have tried:

  1. system("chcp 65001"); — same output (the chcp command succeeds).
  2. x86_64-w64-mingw32-gcc -fexec-charset=utf8 -finput-charset=utf8 — same output.
  3. SetConsoleOutputCP(CP_UTF8); — same output.
  4. wineconsole cmd and run .\test from there — same output.
  5. LANG=en_US.UTF-8 wine ./test.exe — same output.
  6. _setmode(_fileno(stdout), _O_U8TEXT); — no output at all.
  7. Most combinations of the above — no dice.

What I have not tried yet:

  1. Compiling with a Microsoft compiler under Wine.
  2. Compiling with MinGW under Wine.
  3. Compiling and/or running the program under real Windows with either compiler.

How can I fix the non-working case?


Solution

  • I looked it up, and was told that wprintf() usually works with "wide" character formats (e.g. more than one byte character formats). I don't usually use C so I was also curious about how you force a UTF-8 output.

    Also, this from locale.h might help:

        // Set the console to support UTF-8 output
        _setmode(_fileno(stdout), _O_U8TEXT);