【问题标题】:Impossible to put stdout in wide char mode无法将标准输出置于宽字符模式
【发布时间】:2013-11-26 03:35:22
【问题描述】:

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

尽管有这些说明,像这样的小程序

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

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

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

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

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

【问题讨论】:

  • 您不需要宽字符来支持 Unicode。
  • 如果我按字符读取字符,我会这样做,因为我的应用程序处于原始模式,我相信我会这样做 - 但我很可能是错的。

标签: c linux widechar


【解决方案1】:

当 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()

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      更多信息

      【讨论】:

        猜你喜欢
        • 2014-05-31
        • 1970-01-01
        • 2013-12-14
        • 2023-03-20
        • 2017-02-09
        • 1970-01-01
        • 1970-01-01
        • 2019-03-30
        相关资源
        最近更新 更多