我有一个文本文件,foo.txt
,包含以下内容:
R⁸2
我有一个大程序来阅读它并对每个角色做事,但是当它击中⁸
时,它总是收到EOF。以下是代码的相关部分:
setlocale(LC_ALL,"");
FILE *in = fopen(argv[1],"r");
while (1) {
wint_t c = getwc(in);
printf("%d ",wctob(c));
if (c == -1)
printf("Error %d: %sn",errno,strerror(errno));
if (c == WEOF)
return 0;
}
它打印82 -1
(R
和 EOF 的 ASCII 代码(。无论文件中的¹
在哪里,它始终显示为EOF。编辑,我添加了errno
检查,它给出了这个:
Error 84: Invalid or incomplete multibyte or wide character
但是,⁸ 是 Unicode U+2078 "上标八"。我通过cat
和从 fileformat.info 复制粘贴将其写给foo.txt
。foo.txt
的十六进制转储显示:
0000000: 52e2 81b8 32 R...2
怎么了?
1. 检查WEOF
而不是EOF
EOF
适用于单字节字符。WEOF
适用于宽字符。当读取带有getwc
的宽字符的开头时,有时可以返回单字节EOF。
在stdio.h
:
#define EOF (-1)
在wchar.h
:
#define WEOF (0xffffffffu)
2. 将区域设置设置为支持 Unicode 的区域设置
C程序的默认语言环境是C
,也称为POSIX
,它只适用于ASCII。使用setlocale
,有时需要为支持 Unicode 的代码页显式设置适当的语言环境。C.UTF-8
是便携式的。
setlocale(LC_ALL,"C.UTF-8");
setlocale(LC_CTYPE,"C.UTF-8");
3. 对宽字符使用正确的类型
getwc
的返回值不是char
,int
甚至不是wchar_t
,而是wint_t
。确保您的字符变量c
的类型为wint_t
,以避免内存问题。