【问题标题】:Trying to read wide char gives EOF尝试读取宽字符会给出 EOF
【发布时间】:2018-01-20 08:09:07
【问题描述】:

我有一个文本文件 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 的十六进制转储显示:

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

有什么问题?

【问题讨论】:

  • 您需要检查WEOF 而不是EOF,还将int 更改为wint_t。查看文档:cplusplus.com/reference/cwchar/getwc
  • 还有docs for int wctob(wint_t wchar);如果wctob 成功转换了一个宽字符,它返回它的多字节字符表示,只有当多字节字符正好是一个字节长时。如果wctob 遇到无法转换为多字节字符的宽字符或多字节字符不完全是一个字节长,则返回–1
  • @KeineLust 完成,更新。
  • 尝试使用C.UTF-8 或其他一些UTF-8 语言环境。 locale -a 告诉您系统上支持的语言环境是什么?
  • @ChrisDodd 已修复!如果您将其发布为答案,我会接受。另外,你知道为什么setlocale(LC_ALL,""); 没有解决问题吗?我假设可以将其设置为与 Unicode 兼容的代码页。

标签: c file unicode fopen widechar


【解决方案1】:

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 的返回值不是charint 甚至不是wchar_t,而是wint_t。确保您的字符变量c 的类型为wint_t,以避免出现内存问题。

【讨论】:

    猜你喜欢
    • 2014-04-10
    • 1970-01-01
    • 2020-08-31
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多