【问题标题】:How can (byte)Convert.ToChar(anyStringOfLengthOne) possibly throw an error?(byte)Convert.ToChar(anyStringOfLengthOne) 怎么可能抛出错误?
【发布时间】:2011-12-01 11:51:13
【问题描述】:

我们在一个项目中有这个相当简单的代码:

string input = "Any string";
for (int i = 0; i < input.Length; i++)
{
    string stringOfLengthOne = input.Substring(i, 1);
    byte value = (byte)Convert.ToChar(stringOfLengthOne);
    if (value == someValue)
    {
        // do something
    }
}

输入是一个字符串,其中的字符通常从文件中读取,需要根据它们的字节值进行处理。

很遗憾,我们没有机会一步一步调试这个过程,我们只需要做出有根据的猜测可能会导致什么样的字符串

 (byte)Convert.ToChar(anyStringOfLengthOne)

在上面的代码中抛出“算术运算导致溢出”错误。

我的想法是,只要我有一个字符串,就应该总是可以 1. 选择一个字符 2. 将其转换为一个字节。然而错误发生了。

任何想法,提示?或者有人甚至可以提供一个抛出这种错误的字符串吗?

【问题讨论】:

  • 希望你知道byte的范围
  • 我愿意。但是我未能创建一个引发错误的字符串。

标签: c# .net string char byte


【解决方案1】:

.Net 中的字符长度为 16 位(短/超短)。

C# 的默认项目设置意味着强制转换将起作用,并且将忽略任何大于 255 的字符的高位,即像使用 (byte) (c &amp; 0xff)

但是,如果您使用检查算术,尝试强制转换大于 255 的字符将导致 ArithmeticOverflowExcetion。

算术的默认设置可以在项目的构建设置中设置为选中/取消选中。

示例

char c = (char) 300;
byte b = unchecked ((byte) c);
Console.WriteLine (b);

// Result: 44

char c = (char) 300;
byte b = checked ((byte) c);
Console.WriteLine (b);

// Result: ArithmeticOverflowExcetion

另类

或者,您可以直接比较字符。

例如测试一个字符是否为0-9

char c = input[i];
if (c >= '0' && c <= '9') {
    // do something
}

您甚至可以将 char 与 int 进行比较

char c = input[i];
if (c >= 48 && c <= 57) {
    // do something
}

【讨论】:

  • 谢谢。我不知道我们在项目设置中使用了检查算法。我会检查(原文如此!)。
  • 现在 (char)556 也会导致 44 ,不确定 OP 是否只想继续溢出 ....
  • 确实,如果允许溢出,我会添加一个明确的c &amp; 0xff 以使其显而易见,否则我将有一个明确的if (c &gt; 255) { /* handle error */ }
  • 感谢代码改进(顺便说一句,它甚至不是我们的代码)!但是,我仍然无法让代码失败...
  • 输入一个值大于255的字符,音乐高音谱号总是擅长制造麻烦,因为它也需要2个utf-16字符编码,(utf-32) "\U0001D11E"(utf-16) "\uD834\uDD1E"可以输入它使用alt+1D11E
【解决方案2】:

为什么不访问 input[i] 而不是使用 Substring 和 Convert?

编辑:

哦,哦,对不起,我错过了。 .NET (Unicode) 中的字符是 16 位的,因此如果您使用非英文字符,则不能将字符转换为字节是非常合理的。例如,尝试任何希伯来字母。

【讨论】:

  • 那么字符串本身没有编码。如果我添加任何非 us-ascii 字符(尝试了一些野生字符),在我的测试代码中它仍然可以正常工作。我不能让它抛出异常。
  • 有趣。那里有很多疯狂的角色,它可能是任何东西。你为什么不问用户输入是什么?你的代码得到的字符串在某种程度上与用户键入的内容有关,不是吗?
  • 它来自一个 .txt 文件。我们没有机会询问用户(出于各种原因),所以我想从理论上解决这个问题 - 并且可能会得到一个测试场景的好提示。
【解决方案3】:

来自docs

字符串中的每个字符都由一个 Unicode 标量值定义,同样 称为 Unicode 代码点或序号(数字)值 Unicode 字符。每个代码点都使用 UTF-16 进行编码 编码,编码的每个元素的数值为 由 Char 对象表示。

字节是 8 位,UTF-16 是 16 位,这就是你得到错误的原因。

【讨论】:

  • 谢谢,但由于 Chris Chilvers 正确写入,字符 > 255 的高位将被忽略。字符串类型不应该知道编码 - 至少这是我公认的对这些问题的有限知识所暗示的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 2017-03-04
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
相关资源
最近更新 更多