无法将stdout置于宽字符模式

时间:2013-11-13 13:42:09

标签: c linux widechar

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

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

int main() {
  printf("%c", getchar());
  return 0;
}
当用户输入“é”时

失败。

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

我无法相信像cat,grep等每一个实用工具......都会重新实现管理宽字符的方式,但是从我的研究中,我没有别的办法。

我的系统有问题吗?我看不出每个工具如何完美无缺地工作。 我想念的是什么?

3 个答案:

答案 0 :(得分: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(),如果你想用它读取一个宽字符。

答案 1 :(得分:0)

UTF-8字符被视为字节代码而非字符,非ascii字符超过一个字节。 Check this Question

了解更多信息

答案 2 :(得分:0)

您提到的实用程序通常是面向行的。如果你试图阅读整行,例如fgets()而不是单个字符,我认为它也适合你。

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

只要线段终止编码没有被误解(并且对于UTF-8它不会被误解),读取实线就可以正常工作。