C语言 无法将标准输出置于宽字符模式



在我的系统上,一个非常普通的 Ubuntu 13.10,法语重音字符"éèàçù..."无论我使用什么工具,都始终正确处理LC_尽管环境变量设置为 en_US。UTF-8。特别是命令行实用程序,如grep,cat,...始终顺利阅读和打印这些字符。

尽管有这些评论,但像

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

用户输入"é"时失败。

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

我不敢相信每一个实用程序,如cat,grep等......都重新实现了一种管理宽字符的方法,但从我的研究中,我认为没有其他方法。

是我的系统有问题吗?我看不出如何,因为每个实用程序都完美无缺。请问我错过了什么?

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

如果将最小程序扩展到:

#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main()
{
        setlocale(LC_ALL, "");
        printf("%lcn", getwchar());
        return 0;
}

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

但是,如果您想使用它阅读宽字符,您确实需要使用getwchar()而不是getchar()

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

欲了解更多信息

您提到的实用程序通常是面向行的。如果您要尝试阅读整行,例如 fgets() 与其是一个角色,我认为它也会适合你。

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

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

最新更新