0
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
 
 
int main() {
  setlocale(LC_ALL, "");
  wchar_t test = L'づ';

  printf("%ls", L"\x3065");
  printf("%lc", test);

  return 0;     
}

the expected output is: づづ, but these two printf does not print anything, what can i do to solve this problem?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 3
    `L"\x3065"` is not a single character, it's a *string*. Therefore the format specifier and the argument type is not matching, and you will have *undefined behavior*. `L'\x3065'` would be a single character. – Some programmer dude Jul 01 '22 at 18:26
  • Related: [Printing Japanese characters in C program](https://stackoverflow.com/questions/61539991/printing-japanese-characters-in-c-program). – Weather Vane Jul 01 '22 at 18:26
  • printf does not support Unicode most of the time – Anders Jul 01 '22 at 18:32
  • Breno, Tip, what was the return value of `printf("%ls", L"\x3065");`? – chux - Reinstate Monica Jul 01 '22 at 18:45
  • Breno, what _compiler_ are you using? _windows_ is an OS. – chux - Reinstate Monica Jul 01 '22 at 18:48
  • still printing nothing, chux – Breno Macêdo Jul 01 '22 at 18:48
  • gcc version 6.3.0 (MinGW.org GCC-6.3.0-1) – Breno Macêdo Jul 01 '22 at 18:51
  • "What was the return value" doesn't mean "What was it printing?" It is the `int` value `return`ed by `int printf(const char *format [,argument]...);`. *Returns the number of characters printed, or a negative value if an error occurs.* – Weather Vane Jul 01 '22 at 19:03
  • sorry, I misunderstood, the return value was -1 – Breno Macêdo Jul 01 '22 at 19:29
  • 1
    A -1 return value strongly suggests that `printf` has determined that it can not print the requested character in the current locale. – Steve Summit Jul 02 '22 at 01:05
  • 1
    I tried your program unmodified on a Mac and a Debian Linux system, and it printed づづ, as expected. But it's known to be considerably harder to get this sort of thing to work under WIndows. – Steve Summit Jul 02 '22 at 01:06
  • 1
    In my experience, you need to do four separate things to get this to work right. (1) You need to use a wide-character-aware `printf` format, like `%ls` or `%lc`. You've got that. (2) You need to call `setlocale(LC_ALL, "")`, so that the C library knows it's allowed to use locale-specific output transformations. You've got this. (3) You need to have your output device — your terminal window or whatever — set to a mode that knows how to print wide characters. I don't know how to do this under Windows, and many people have trouble with it, and I suspect it's your problem. – Steve Summit Jul 02 '22 at 01:11
  • 1
    (4) You need to have your environment set up to communicate to your C program what your terminal window (or whatever) is set to. I have no idea how you do this under Windows, either. For me, to do (3) I set the Mac Terminal display character set to UTF-8, and to do (4) I set the environment variable LANG to "en_US.UTF-8". (What's important is that LANG contain the substring "UTF-8". Since Unicode is multilingual, there's no problem displaying Japanese text even though my locale is set to en_US.) – Steve Summit Jul 02 '22 at 01:11
  • There's a bunch of good information at http://utf8everywhere.org/ . – Steve Summit Jul 02 '22 at 01:37

1 Answers1

2

printf is a narrow string function and unless you have requested UTF-8 in your manifest and are running on an appropriate version Windows 10 it is not going to print Unicode correctly in all cases.

Use wprintf to print wide strings. Depending on the C runtime library, you might need to call _setmode(_fileno(stdout), _O_U16TEXT); first before printing.

Even if your program does everything correctly it might still not work in the console. Using the new Windows Terminal should work. The older console might just display squares. This is a console/font limitation. Copy the squares to the clipboard and paste in Wordpad to see that your program actually worked correctly.

See also:

Anders
  • 97,548
  • 12
  • 110
  • 164
  • *`printf` is a narrow string function* I would say that it is a "narrow" string function *by default*. But it's supposed to be able to print "wide" characters also, as long as you use `%lc` or `%ls`. Indeed this works for me all the time, and I never use `wprintf`. But then again, I don't use Windows, so I may be spoiled/biased. – Steve Summit Jul 02 '22 at 01:26
  • @SteveSummit On Windows, it will always understand wide input like %ls but the function itself (depending on the C library implementation) will probably convert from WCHAR to the active codepage and unless you have forced UTF-8 or have a Japanese locale the conversion will fail. Or in simpler terms, it will understand wide input but it might not be able to present those characters in the output. – Anders Jul 02 '22 at 02:02
  • I see. Thanks for the clarification. But `wprintf` is able to do better somehow? – Steve Summit Jul 02 '22 at 02:25
  • @Steve Yes, `wprintf` on Windows is wide (UTF-16LE) all the way from input to output. – Anders Jul 02 '22 at 02:38