我正试图从一个虚拟中读取汉字,我在这里找到了一些关于这个问题的问题,但没有什么对我有用或适合我的需要。我正在使用来自this question的fread()实现,但它不起作用。我正在运行Linux。
#define UNICODE
#ifdef UNICODE
#define _UNICODE
#else
#define _MBCS
#endif
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char * argv[]) {
FILE *infile = fopen(argv[1], "r");
wchar_t test[2] = L"\u4E2A";
setlocale(LC_ALL, "");
printf("%ls\n", test); //test
wcscpy(test, L"\u4F60"); //test
printf("%ls\n", test); //test
for (int i = 0; i < 5; i++){
fread(test, 2, 2, infile);
printf("%ls\n", test);
}
return 0;
}
我使用以下文本文件来测试它:
一个人
两本书
三张桌子
我喜欢一个猫
和程序输出:
个
你
������
任何人都有关于这个问题的任何智慧?
编辑:此外,这是我的所有代码,因为我不确定它失败的地方。那里有一些我测试的东西,以确保我可以打印与问题不完全相关的unicode wchars。
答案 0 :(得分:1)
如果您确实需要一次读取UTF-8(或者更确切地说是区域设置charmap)文件,则可以使用fscanf
,如下所示。但请注意,这是代码点而不是字符,由于组合代码,字符可能包含多个代码点,而且某些代码点绝对不可打印。
#include <locale.h>
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
FILE *infile = fopen(argv[1], "r");
wchar_t test[2] = L"\u4E2A";
setlocale(LC_ALL, "");
printf("%ls\n", test); //test
wcscpy(test, L"\u4F60"); //test
printf("%ls\n", test); //test
for (int i = 0; i < 5; i++) {
fscanf(infile, "%1ls", test);
printf("%ls\n", test);
}
return 0;
}
大多数情况下,您可能不需要使用区域设置功能,因为如果将UTF-8视为不透明编码,它通常会起作用。部分原因是因为所有非ASCII字符的全部其组件字节在128..253范围内(不是拼写错误,254和255未使用)另一部分是字节128..159始终是连续字节字符的所有起始字节都是160..253,这意味着错误只会破坏一个字符而不是流的其余部分。 (好吧,代码点vs字符真的只是试图说服你将UTF-8划分为“字符”可能不会做你想要的)。
答案 1 :(得分:0)
您告诉fread
在每次通话中读取两个2字节值;但是,您要读取的字符具有3字节UTF-8编码。通常,您需要整体解码UTF-8流,而不是固定大小的字节块。