fwprintf省略了广泛的字符

我正在尝试使用Windows上的MinGW C创建宽字符文件,但似乎省略了宽字符。 我的代码:

const wchar_t* str = L"příšerně žluťoučký kůň úpěl ďábelské ódy"; FILE* fd = fopen("file.txt","w"); // FILE* fd = _wfopen(L"demo.txgs",L"w"); // attempt to open wide file doesn't help fwide(fd,1); // attempt to force wide mode, doesn't help fwprintf(fd,L"%ls",str); // fputws(p,fd); // stops output after writing "p" (1B file size) fclose(fd); 

文件内容

 píern luouký k úpl ábelské ódy 

文件大小为30B,因此广泛的字符真的丢失了。 如何说服编译器编写它们?

正如@chqrlie在评论中所说:结果

 fwrite(str, 1, sizeof(L"příšerně žluťoučký kůň úpěl ďábelské ódy"), fd); 

是82(我猜2 * 30 + 2 * 10(ommited chars)+ 2(宽尾零))。

从这里引用也可能有用

文件中宽字符的外部表示是多字节字符:这些字符就像调用wcrtomb来转换每个宽字符一样(使用流的内部mbstate_t对象)。

这解释了为什么ISO-8859-1字符在文件中是单字节,但我不知道如何使用这些信息来解决我的问题。 执行相反的任务(将多字节UTF-8读入宽字符)我未能使用mbtowc并最终使用winAPI的MultiByteToWideChar 。

我想出来了。 wcrtomb的内部使用(在我的问题的细节中提到)需要setlocale调用,但该调用在Windows上使用UTF-8失败。 所以我在这里使用了winAPI:

 char output[100]; // not wchar_t, write byte-by-byte int len = WideCharToMultiByte(CP_UTF8,0,str,-1,NULL,0,NULL,NULL); if(len>100) len = 100; WideCharToMultiByte(CP_UTF8,0,str,-1,output,len,NULL,NULL); fputs(output,fd); 

瞧! 该文件长度为56B,具有预期的UTF-8内容:

 příšerně žluťoučký kůň úpěl ďábelské ódy 

我希望这会为Windows程序员节省一些麻烦。

我不是Windows用户,但您可以尝试这样做:

 const wchar_t *str = L"příšerně žluťoučký kůň úpěl ďábelské ódy"; FILE *fd = fopen("file.txt", "w,ccs=UTF-8"); fwprintf(fd, L"%ls", str); fclose(fd); 

我从这个问题中得到了这个想法: 如何在Windows中用Windows编写UTF-8编码的字符串