Как (byte) Convert.ToChar (anyStringOfLengthOne) возможно выдать ошибку? - PullRequest
1 голос
/ 01 декабря 2011

У нас есть довольно простой код в проекте:

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. преобразовать его в байт.И все же ошибка возникает.

Есть идеи, намеки?Или кто-то может даже привести строку, которая выдает такую ​​ошибку?

Ответы [ 3 ]

2 голосов
/ 01 декабря 2011

Символы в .Net имеют длину 16 бит (короткая / короткая).

Настройки проекта по умолчанию для C # означают, что приведение будет работать и будет просто игнорировать старшие биты для любого символа, который больше, чем 255, т.е. как использование (byte) (c & 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
}
1 голос
/ 01 декабря 2011

Из документов

Каждый символ в строке определяется скалярным значением Unicode, также называется кодовой точкой Unicode или порядковым (числовым) значением Юникод символ Каждая кодовая точка кодируется с помощью UTF-16 кодирование, а числовое значение каждого элемента кодирования представленный объектом Char.

Байт 8 бит, UTF-16 16 бит, поэтому вы получаете ошибку.

1 голос
/ 01 декабря 2011

Почему бы не получить доступ к входу [i] вместо использования подстроки и преобразования?

EDIT:

Ох, простите, я пропустил это. В .NET (Unicode) 16-битные символы, поэтому очень разумно, что вы не можете преобразовать символ в байт, если используете не английские символы. Попробуйте любое письмо на иврите, например.

...