在我的系统上,一个非常正常的Ubuntu 13.10,法语重音字符“éèàçù...”总是通过我使用的任何工具正确处理,尽管LC_环境变量设置为en_US.UTF-8。 特别是命令行实用程序,如grep,cat,...总是读取并打印这些字符。
尽管有这些评论,这样的小程序如
int main() {
printf("%c", getchar());
return 0;
}
当用户输入“é”时失败。
从手册页和大量的谷歌搜索中,没有标准的方法来关闭标准输出,然后重新打开它。从man fwide(),如果stdout处于字节模式,我不能将它传递给宽字符模式,不能关闭它并重新打开它...因此我不能使用getwchar()和wprintf()。
我无法相信像cat,grep等每一个实用工具......都会重新实现管理宽字符的方式,但是从我的研究中,我没有别的办法。
我的系统有问题吗?我看不出每个工具如何完美无缺地工作。 我想念的是什么?
答案 0 :(得分:3)
当C程序启动时,stdout
,stdin
和stderr
既不是字节也不是宽字符。 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它不会被误解),读取实线就可以正常工作。