为什么string.IsNullOrWhiteSpace("\0")为false

6

我遇到了一个问题,即不可见字符\0,它非常像一个“空格”,但却不被字符串方法 IsNullOrWhiteSpace 视为空格。我想知道为什么.NET以这种方式实现,并且是否有替代的方法可以正确处理空终止字符?谢谢。


2
空值不是空格。你想做什么? - SLaks
'\0' 不是空格。 - Emmanuel N
你在解密什么吗?我经常看到\0与错误填充的解密字符串... - xanatos
不,这是由同一应用程序写入的CSV文件的最后一行。不确定为什么会发生这种情况,但希望使应用程序能够读取即使是这样的“不理想”文件。 - Shoar
6个回答

19

U+0000不是空格,基本上。 char.IsWhitespace('\ 0')返回false,它没有被列为空格…

IsNullOrWhitespace中的null部分指的是字符串引用本身 - 而不是内容,如果这是您所考虑的。

请注意,在托管代码中,.NET中的字符串在逻辑上并不是“以null结尾”的,尽管在CLR级别上实际上是为了互操作的目的。 (字符串知道自己的长度,但为了使其更容易与期望空终止符的本地代码一起使用,CLR确保字符串内容后始终有一个U + 0000。)如果你最终得到包含\0 的字符串,你应该修复产生它的任何问题。


请注意,在.NET中,字符串不是“以null结尾”的。这句话有点不准确...虽然C语言中的NUL终止符存在但不可见(strlen不计算它,printf("%s", str)不打印它...),但在C#中也是一样的(string以NUL结尾以便于交互操作,但这个东西是看不见的)。 - xanatos
@xanatos:没错,会修复的。 - Jon Skeet
/0是用户的空白字符,因为它不能表示为任何可见字符,但占据了位置。所以我认为string.IsNullOrWhiteSpace也应该将其视为空格。根据您的描述,我理解'/0'在.NET字符串中通常不会出现,可能正因为如此,.NET程序员没有将其列入空格字符列表。感谢您的解释。 - Shoar
2
@Shoar:不,那不是空格的定义。这可能是“不可打印字符”的定义,但这与空格不同。这不是.NET决定的问题 - 这是Unicode类别的问题。 - Jon Skeet

5

您可以将所有的 \0 字符替换为空格字符,然后检查空白字符。

string.IsNullOrWhiteSpace("\0".Replace('\0', ' ');

1
好的,如果你要这样做的话,使用IndexOf会更简单和更快。 - Luaan
嗯,你需要知道是否所有字符都是空格或\0...在这种情况下,使用.All(c => char.IsWhiteSpace(c) || c == '\0')。仍然比替换快,并且避免了对于典型字符串的大量迭代(和复制)。 - Luaan
这取决于字符串的长度,对于较长的字符串,您的解决方案效果更好,但对于较短的字符串,replace方法更快。(刚刚测试过) - Cyral
这很不太可能——IsNullOrWhiteSpace的内部实现只是一个简单的C#循环。也许这只是LINQ的开销?那么,您可以自己使用for循环。我之所以使用LINQ是为了可读性。 - Luaan
可能是LINQ的开销,我想一个for循环与.NET实现一样快。 - Cyral

4
出于有趣的历史原因(它们肯定很有趣,但我找不到相关资料),null 有两个含义... null 指针/引用(在 C 中称为 NULL),以及 NUL(或 NULL\0 字符。 String.IsNullOrWhiteSpace 方法的作用如下:

指示指定的字符串是否为 null、空或仅由空白字符组成。

其中,null 表示 "null 引用",empty 表示为空,white-space 表示

空格字符由 Unicode 标准定义。当传递给 Char.IsWhiteSpace 方法时返回 true 的任何字符都被 IsNullOrWhiteSpace 方法解释为空格字符。

Char.IsWhiteSpace 方法认为是空格的字符列表可在 Char.IsWhiteSpace 页面中找到。

2
'\0'字符不被视为空格。请参见Char.IsWhitespace()获取被视为空格的字符列表。
如果您有自己的要求,或者只是想添加几个字符,请使用Enumerable.All()。可以像这样做:
bool IsMyKindOfWhiteSpace(string input)
{
    char[] more = new char[] { <here goes your list of additional white space chars> };

    return input.All(x => Char.IsWhiteSpace(x) || more.Contains(x));
}

1
创建一个扩展方法,将空字符作为检查项添加。
public bool IsNullOrWhitespaceOrHasNullChar(this string text)
{
   return string.IsNullOrWhiteSpace(text) || Regex.IsMatch(text, "\0");
}

如果字符串中存在空字符,它将被发现并报告为此类情况,因此带有“a\0”的字符串将返回true。 如果这是一个问题,请创建一个检查完整字符串\0的测试。

1
使用正则表达式来处理这么简单的任务可能过于极端,特别是在性能方面。 - Shoar

0

NULL字符串与空字符串或空格不同


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接