我正在尝试制作自己的wc(Unix过滤器),但在处理非ASCII字符时遇到了问题。我对文本文件进行了HEX转储,发现这些字符占用多个字节,因此无法适应char类型。是否有办法在C中从文件中读取这些字符并像单个字符一样处理它们(以便计算文件中的字符数量)?
我已经进行了一些谷歌搜索,并找到了一些wchar_t类型,但没有任何简单的示例说明如何将其与文件一起使用。
我已经进行了一些谷歌搜索,并找到了一些wchar_t类型,但没有任何简单的示例说明如何将其与文件一起使用。
u_fgetc
函数,并且将Unicode支持添加到程序中可能只需要多输入几次u_
。个人而言,我从未使用过ICU,但从现在开始我可能会用它了 :-)
如果你想编写一个符合当前语言设置的标准C版本的wc
实用程序,那么你确实可以使用stdio函数的wchar_t
版本。在程序启动时,你应该调用setlocale()
:
setlocale(LC_CTYPE, "");
LANG
环境变量。例如,这意味着如果您的 LANG
变量设置为 UTF8
区域设置,则宽字符函数将处理 UTF8 的输入和输出。(这是 POSIX wc
工具的规定操作方式)。long words = 0;
int in_word = 0;
int c;
while ((c = getchar()) != EOF)
{
if (isspace(c))
{
if (in_word)
{
in_word = 0;
words++;
}
}
else
{
in_word = 1;
}
}
如果您想将其转换为宽字符版本,则需要将c
更改为wint_t
,将getchar()
更改为getwchar()
,将EOF
更改为WEOF
,将isspace()
更改为iswspace()
:
long words = 0;
int in_word = 0;
wint_t c;
while ((c = getwchar()) != WEOF)
{
if (iswspace(c))
{
if (in_word)
{
in_word = 0;
words++;
}
}
else
{
in_word = 1;
}
}
到目前为止,大多数答案都有其优点,但使用哪个取决于您想要的语义:
getwchar()
就可以了。mbrtowc
。00-7F
和C2-F4
并跳过计算所有其他字节,但这可能会在存在无效序列的情况下产生错误结果。更可靠的方法是将字节流解码为Unicode代码点并计算成功解码的数量。希望这可以帮助您。
你确定你真的需要字符数量吗?wc
会计算字节数量。
~$ echo 'דניאל' > hebrew.txt
~$ wc hebrew.txt
1 1 11 hebrew.txt
(11 = 5个双字节字符 + 1个字节的 '\n')
然而,如果你真的想要计算字符而不是字节,并且可以假设你的文本文件是以 UTF-8 编码的,那么最简单的方法是计算所有不是尾随字节(即在 0x80 到 0xBF 范围内)的字节。
如果你不能假设 UTF-8 但可以假设任何非 UTF-8 文件都是单字节编码,则对数据执行 UTF-8 验证检查。如果通过,则返回 UTF-8 前导字节的数量。如果失败,则返回总字节数。
(请注意,上述方法特定于 wc
。如果你实际上正在处理字符而不仅仅是计数它们,则需要知道编码方式。)
wc -m
确实计算的是字符数,而不是字节数 - wc -m hebrew.txt
的输出结果为 6 hebrew.txt
。 - caf