尝试读取宽字符会给出 EOF

Trying to read wide char gives EOF

我有一个文本文件 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: %s\n",errno,strerror(errno));

    if (c == WEOF)
        return 0;
}

它打印 82 -1R 和 EOF 的 ASCII 码)。无论文件中的 ¹ 在哪里,它总是读作 EOF。 编辑,我为 errno 添加了一个检查,它给出了这个:

Error 84: Invalid or incomplete multibyte or wide character

然而,⁸ 是 Unicode U+2078 'SUPERSCRIPT EIGHT'。我通过 cat 将其写入 foo.txt 并从 fileformat.info 复制粘贴。 foo.txt 的 hexdump 显示:

0000000: 52e2 81b8 32                             R...2

有什么问题?

1。检查 WEOF 而不是 EOF

EOF 用于单字节字符。 WEOF 用于宽字符。使用 getwc 读取宽字符的开头时,单字节 EOF 有时会被 returned.

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 的 return 值不是 charint 甚至 wchar_t,而是 wint_t。确保你的字符变量 cwint_t 类型,以避免内存问题。