【发布时间】:2015-06-21 06:01:39
【问题描述】:
考虑以下程序:
#include <stdio.h>
#include <string.h>
int main() {
char* alpha = "Ω";
fwrite(alpha, 1, strlen(alpha), stdout);
return 0;
}
在 Windows 上,我得到以下输出:
��
我尝试将行更改为:
char* alpha = "zΩ";
并且打印正确。输出编码正确,只是不打印 正确:
$ 坏 | od-tx1c 0000000 ce a9 316 251 $ 好 | od-tx1c 0000000 7a ce a9 z 316 251如何使用 fwrite 以非 ASCII 作为第一个字符?
回复部分cmets:源文件正确格式化为UTF-8,我的代码页也正确设置为UTF-8:
$ chcp.com 活动代码页:65001【问题讨论】:
-
调用
_setmode(_fileno(stdout), _O_U16TEXT),然后使用fwrite写一个wchar_t *宽字符串。由于底层 CRT 文件是 UTF-16 模式,并且是一个控制台,所以写入是通过调用 Unicode APIWriteConsoleW来实现的。 -
这对我有用:
wchar_t *alpha = L"Ω";_setmode(_fileno(stdout), _O_U16TEXT);fwrite(alpha, 2, wcslen(alpha), stdout); -
{0xa9, 0x03} 是“Ω”的小端 UTF-16,即 U+03A9。您是使用普通的 Windows 控制台来运行它还是在 POSIX shell 中运行,该 shell 管道连接到某种 pty 实现?检查
GetFileType(GetStdHandle(STD_OUTPUT_HANDLE))。是FILE_TYPE_CHAR(2,控制台缓冲区句柄)还是FILE_TYPE_PIPE(3)? -
好吧,如果它调用
WriteFile而不是WriteConsoleW,那么这将不起作用。对不起。如果_setmode成功,请尝试调用wprintf或fwprintf。 -
我认为在这种情况下,将 Ω 写为 UTF-8 字符串
"\xce\xa9"的问题在于,fwrite在写入第一个字节时会刷新其缓冲区。据我所知,仅东亚语言环境中的 DBCS 支持跨写入拆分多字节字符串,而不支持 UTF-8。 (实际上,当语言环境不是默认的 C 语言环境时,Microsoft 的 CRT 对 DBCS 有特殊支持。)因此控制台尝试将"\xce"和"\xa9"解码为两个单独的 UTF-8 字符串。如果您添加一个初始的"z"字节,那么"\xce\xa9"可能会在对WriteFile的一次调用中写入。
标签: c windows fwrite non-ascii-characters