2

1 wprintf 显示 'Ω' 为 3A9 (UTF16) 真的很奇怪,但是 wctomb 将 wchar 转换为 CEA9 (UTF8),我的语言环境默认为 en_US.utf8。正如手册页所说,它们应该符合我的语言环境,但是 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]);
}
4

3 回答 3

6

第二个问题的答案与流向有关。你不能混合printf()wprintf()因为它们需要不同的方向。

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

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

于 2011-10-09T00:44:08.363 回答
2

您如何确定该wprintf行正在打印什么?您在问题下方的评论似乎暗示您只是在检查 的结果,无论字符编码如何wprintf ("%x", myChar1);,它都会打印内部数值myChar1(但不考虑字符集 - 存在差异);假设您的编译器在wchar_t内部对 s 使用 Unicode(我相信这是一个非常安全的选择),这只会打印出 'Ω' 的 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

请注意,欧米茄以 UTF-8 编码为字节 CE A9,但其数值wchar_t仍然是 3A9。

于 2011-10-09T02:46:43.827 回答
0

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

setlocale(LC_ALL, "")

第一的。看起来 wchar I/O 函数不支持 LC_ 环境变量。

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

于 2012-05-25T19:38:35.660 回答