Linux上的wprintf UTF16(应该是UTF8)?

时间:2011-10-09 00:40:35

标签: c linux console wchar-t wchar

1 wprintf显示'Ω'为3A9(UTF16),但是wctomb转换真的很奇怪 wchar到CEA9(UTF8),我的语言环境是默认的en_US.utf8。正如man-pages所说, 他们应该符合我的语言环境,但是wpritnf使用UTF16,为什么?

摘自http://www.fileformat.info/info/unicode/char/3a9/index.htm

UTF中的

Ω

UTF-8(十六进制)0xCE 0xA9(cea9)

UTF-16(十六进制)0x03A9(03a9)

2 wprintf和printf只是无法在同一个程序中运行,我有 选择使用wprintf或printf,为什么?


查看我的计划:

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

int main() {
  setlocale(LC_ALL,""); // inherit locale setting from environment
  int r;
  char wc_char[4] = {0,0,0,0};
  wchar_t myChar1 = L'Ω'; //greek 

  // should comment out either wprintf or printf, they don't run together
  r = wprintf(L"char is %lc (%x)\n", myChar1, myChar1);//On Linux, to UTF16

  r = wctomb(wc_char, myChar1); // On Linux, to UTF8
  r = printf("r:%d, %x, %x, %x, %x\n", r, wc_char[0], wc_char[1], wc_char[2], wc_char[3]);
}

3 个答案:

答案 0 :(得分:5)

第二个问题的答案与stream orientation有关。您不能混用printf()wprintf(),因为它们需要不同的方向。

当进程启动时,尚未设置流。在第一次调用使用该流的函数时,它会相应地进行设置。 printf()会将方向设置为正常,wprintf()会将其设置为宽。

调用需要与当前设置不同方向的函数是未定义的行为。

答案 1 :(得分:2)

您究竟如何确定wprintf行正在打印的内容?您在问题下方的评论似乎意味着您只是检查wprintf ("%x", myChar1);的结果,它会打印myChar1的内部数值而不管字符编码(但不管字符集如何 - 都有区别);假设您的编译器在内部使用Unicode wchar_t s(我相信这是一个相当安全的选择),这只是打印出'Ω'的Unicode代码点,即0x3a9,独立于UTF-16与UTF-8区别。为了判断wprintf是否正在打印UTF-16,您必须直接检查输出的原始字节(例如,使用hexdump(1))。例如,在我的计算机上,wprintf行打印以下内容:

63 68 61 72 20 69 73 20 ce a9 20 28 33 61 39 29 0a
c  h  a  r     i  s     Ω        (  3  a  9  )  \n

请注意,omega以UTF-8编码为字节CE A9,但wchar_t的数值仍为3A9。

答案 2 :(得分:0)

啊,我可能已经找到了。你需要执行

setlocale(LC_ALL, "")

第一。看起来wchar I / O函数不符合LC_环境变量。

有关更多背景信息,请参阅http://littletux.homelinux.org/knowhow.php?article=charsets/ar01s08