另一个问题。 Unicode,终端以及现在的C#和wc
。如果我写这段简单的代码
int i=0;
foreach(char c in Console.In.ReadToEnd())
{
if(c!='\n') i++;
}
Console.WriteLine("{0}", i);
并仅输入字符“€”(utf-8中的3个字节),wc
返回3个字符(可能使用wint_t,但我没有检查过),但ReadToEnd()
返回1 (一个字)。在这种情况下ReadToEnd
的行为究竟是什么?我怎么知道ReadToEnd
在幕后做了什么?
我正在使用utf-8.en.US运行xterm,运行Ubuntu Linux和Mono。
谢谢。
答案 0 :(得分:3)
wc
和大多数类似unix的命令根据C char
数据类型处理字符,该数据类型通常是无符号的8位整数。 wc
只是逐个读取标准输入中的字节而没有转换,并确定有3个字符。
.NET根据自己的Char
数据类型处理字符,该数据类型是16位无符号整数,表示UTF-16字符。控制台类已收到3个字节的输入,确定它所连接的控制台是UTF-8并正确地将它们转换为单个UTF-16欧元字符。
答案 1 :(得分:3)
您需要考虑字符编码。目前,您只是计算字节数,而char
和byte
s的大小不一定相同。
Encoding encoding = Encoding.UTF8;
string s = "€";
int byteCount = encoding.GetByteCount(s);
Console.WriteLine(byteCount); // prints "3" on the console
byte[] bytes = new byte[byteCount];
encoding.GetBytes(s, 0, s.Length, bytes, 0);
int charCount = encoding.GetCharCount(bytes);
Console.WriteLine(charCount); // prints "1" on the console
答案 2 :(得分:2)
ReadToEnd返回一个字符串。 .NET中的所有字符串都是Unicode。它们不仅仅是一个字节数组。
显然,wc正在返回字节数。字节数和字符数曾经是相同的。
答案 3 :(得分:1)
wc
返回文件中的行数,字数和字节数。如果您想根据活动区域设置的编码返回字符数而不仅仅是字节数,那么您应该查看现代-m
的{{1}}或--chars
选项有