1

在我的系统上,一个非常普通的 Ubuntu 13.10,尽管 LC_ 环境变量设置为 en_US.UTF-8,但我使用的任何工具始终可以正确处理法语重音字符“éèàçù...”。特别是像 grep, cat, ... 这样的命令行实用程序总是可以顺利读取和打印这些字符。

尽管有这些评论,但像这样的小程序

int main() {
  printf("%c", getchar());
  return 0;
}

当用户输入“é”时失败。

从手册页和大量谷歌搜索来看,没有标准的方法可以关闭标准输出,然后重新打开它。从 man fwide() 开始,如果 stdout 处于字节模式,我不能将它传递给宽字符模式,除非关闭它并重新打开它......因此我不能使用 getwchar() 和 wprintf()。

我不敢相信像 cat、grep 等每一个实用程序都重新实现了一种管理宽字符的方法,但根据我的研究,我看不到其他方法。

是我的系统有问题吗?我看不出每个实用程序如何完美运行。请问我错过了什么?

4

3 回答 3

3

当 C 程序启动时stdoutstdinstderr既不是字节也不是面向宽字符的。 fwide(stdin, 0)此时应返回 0。

如果您将最小程序扩展为:

#include <stdio.h>
#include <locale.h>
#include <wchar.h>

int main()
{
        setlocale(LC_ALL, "");
        printf("%lc\n", getwchar());
        return 0;
}

然后它应该按您的预期工作。(这里不需要显式设置的方向stdin- 因为它的第一个操作是宽字符操作,它将具有宽字符方向)。

不过,如果你想用它来阅读一个宽字符,你确实需要使用getwchar()而不是。getchar()

于 2013-11-13T13:59:05.720 回答
0

UTF-8 字符被视为字节码而不是字符和非 ascii 字符超过一个字节。 检查这个问题

了解更多信息

于 2013-11-13T13:49:18.423 回答
0

您提到的实用程序通常是面向行的。如果您要尝试使用 egfgets()而不是单个字符来阅读整行,我认为它也对您有用。

当您开始读取单个字符(可能只是字节,而且通常是)时,您当然很容易受到编码问题的影响。

只要不误解行终止编码(对于 UTF-8 则不会),读取整行就可以了。

于 2013-11-13T13:49:29.630 回答