开发者

Why printf doesn't print what I feed it with?

开发者 https://www.devze.com 2023-04-11 22:50 出处:网络
printf(\"%s\\n\", \"ああ\"); It outputs : ã‚ã‚ What else should I 开发者_高级运维do to print it correctly?Assuming that\'s unicode, compile with a C99 compiler
printf("%s\n", "ああ");

It outputs :

ã‚ã‚

What else should I 开发者_高级运维do to print it correctly?


Assuming that's unicode, compile with a C99 compiler

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

int main(void) {
  wchar_t buff[3]; // = L"ああ";
  buff[0] = buff[1] = L'\U00003042';
  buff[2] = 0;
  setlocale(LC_ALL, "");
  wprintf(L"%ls\n", buff);
  return 0;
}


The absolutely correct version should look like this:

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

int main()
{
        wchar_t *s1 = L"♠♣♥♦";
        wchar_t *s2 = L"Příšerně žluťoučký kůň";
        wchar_t *s3 = L"ああ";

        setlocale(LC_ALL,""); /* pull system locale for correct output */
        wprintf(L"%ls\n%ls\n%ls\n",s1,s2,s3); /* print all three strings */
        return 0;
}

Edit:

As pointed out in the comments by R.., you can actually use printf instead of wprintf. The only limitation is that the formating string must be const char* for the printf instead of const wchar_t* for wprintf. So no wide characters in the formatting string.


I think you might have to use wprintf, the wide character version of printf.


Technically, C89 doesn't support mutli-byte encoding for string literals (only ASCII), standard C functions can handle input/output with other encodings, provided it can be treated as an opaque blob.

E.g., this one will be correct:

#include <stdio.h>
int main() {
    printf("%s\n", "\xe3\x81\x82\xe3\x81\x82");
}

This one may be wrong (if you expect it to print the number of characters):

#include <stdio.h>
#include <string.h>
int main() {
    printf("%lu\n", strlen("\xe3\x81\x82\xe3\x81\x82"));
}

The compiler may interpret source input as UTF-8, but it's not guaranteed. For example, GCC does seem to read UTF-8 source files correctly:

hexdump -Cv b.c
00000000  23 69 6e 63 6c 75 64 65  20 3c 73 74 64 69 6f 2e  |#include <stdio.|
00000010  68 3e 0a 69 6e 74 0a 6d  61 69 6e 28 29 0a 7b 0a  |h>.int.main().{.|
00000020  20 20 20 20 70 72 69 6e  74 66 28 22 25 73 5c 6e  |    printf("%s\n|
00000030  22 2c 20 22 e3 81 82 e3  81 82 22 29 3b 0a 7d 0a  |", "......");.}.|
00000040

Note the same string is the literal (e3 81 82 e3 81 82) and is exactly the same byte sequence that gets printed out:

./a.out | hexdump -Cv
00000000  e3 81 82 e3 81 82 0a                              |.......|
00000007

If your locale isn't UTF-8, or your editor saved the file with encoding other than UTF-8, I suspect the result will be different.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号