cdonts
cdonts

Reputation: 9599

Output unicode wchar_t character

Just trying to output this unicode character in C using MinGW. I first put it on a buffer using swprintf, and then write it to the stdout using wprintf.

#include <stdio.h>

int main(int argc, char **argv)
{
    wchar_t buffer[50];
    wchar_t c = L'☒';

    swprintf(buffer, L"The character is: %c.", c);
    wprintf(buffer);

    return 0;
}

The output under Windows 8 is:

The character is: .

Other characters such as Ɣ doesn't work neither.

What I am doing wrong?

Upvotes: 2

Views: 1188

Answers (4)

Robert S. Barnes
Robert S. Barnes

Reputation: 40548

This FAQ explains how to use UniCode / wide characters in MinGW:

https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/

Upvotes: 0

user3889642
user3889642

Reputation: 31

To output Unicode (or to be more precise UTF-16LE) to the Windows console, you have to change the file translation mode to _O_U16TEXT or _O_WTEXT. The latter one includes the BOM which isn't of interest in this case.

The file translation mode can be changed with _setmode. But it takes a file descriptor (abbreviated fd) and not a FILE *! You can get the corresponding fd from a FILE * with _fileno.

Here's an example that should work with MinGW and its variants, and also with various Visual Studio versions.

#define _CRT_NON_CONFORMING_SWPRINTFS

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

int
main(void)
{
    wchar_t buffer[50];
    wchar_t c = L'Ɣ';

    _setmode(_fileno(stdout), _O_U16TEXT);
    swprintf(buffer, L"The character is: %c.", c); 
    wprintf(buffer);

    return 0;
}

Upvotes: 3

Dietrich Epp
Dietrich Epp

Reputation: 213258

You're using %c, but %c is for char, even when you use it from wprintf(). Use %lc, because the parameter is whar_t.

swprintf(buffer, L"The character is: %lc.", c);

This kind of error should normally be caught by compiler warnings, but it doesn't always happen. In particular, catching this error is tricky because both %c and %lc actually take int arguments, not char and wchar_t (the difference is how they interpret the int).

Upvotes: 5

ouah
ouah

Reputation: 145829

This works for me:

#include <locale.h>
#include <stdio.h>
#include <wchar.h>

int main(int argc, char **argv)
{
    wchar_t buffer[50];
    wchar_t c = L'☒';

    if (!setlocale(LC_CTYPE, "")) {
        fprintf(stderr, "Cannot set locale\n");
        return 1;
    }

    swprintf(buffer, sizeof buffer, L"The character is %lc.", c);
    wprintf(buffer);

    return 0;
}

What I changed:

  • I added wchar.h include required by the use of swprintf
  • I added size as the second argument of swprintf as required by C
  • I changed %c conversion specification to %lc
  • I change locale using setlocale

Upvotes: 2

Related Questions