Преобразовать символы, соответствующие цифрам, в uint

Мне нужно обойти строку, которая должна быть строкой цифр и сделать некоторые арифметические операции над этими цифрами

for (int i = data.Length - 1; i >= 0; --i)
  {
       uint curDigit;
       //Convert  to uint the current rightmost digit, if convert fails return false (the valid data should be numeric)
       try
       {
           curDigit = Convert.ToUInt32(data[i]);
           //arithmetic ops...
       }
       catch
       {
         return false;
       }

Я проверяю это с помощью следующей строки входных данных. "4000080706200002" для i = 15, соответствующий самой правой цифре 2,Я получил 50 как вывод из

curDigit = Convert.ToUInt32(data[i]);

Может кто-нибудь объяснить, пожалуйста, что не так? И как исправить проблему

5 ответов

50 - это код ASCII для '2', что тебе нужно '2' - '0' (50-48)

byte[] digits = "4000080706200002".Select(x => (byte)(x - '0')).ToArray();

http://www.asciitable.com/

То, что вы получаете обратно, это значение характера ascii 2Вы можете использовать звонок ToString на предмете персонажа, а затем позвоните Convert.ToUnit32Рассмотрим пример:

char x = '2';
uint curDigit = Convert.ToUInt32(x.ToString());

это вернет тебя 2 как curDigit

Для вашего кода вы можете просто использовать:

curDigit = Convert.ToUInt32(data[i].ToString());

Другой вариант - использовать char.GetNumericValue, например:

uint curDigit = (UInt32) char.GetNumericValue(data[i]);

char.GetNumericValue возвращается double и вы можете привести результат обратно к UInt32

Проблема в том, что data [i] возвращает char переменная, которая по сути является целым числом, содержащим ASCII-код символа. Таким образом, "2" соответствует 50. Есть две вещи, которые вы можете сделать, чтобы преодолеть это поведение:

  1. Лучше curDigit = Convert.ToUInt32(data[i] - '0'); // Вычитаем ASCII-представление '0' из символа
  2. curDigit = Convert.ToUInt32(data.Substring(i,1)); // Используем подстроку для возврата строки вместо char. Обратите внимание, что этот метод менее эффективен, так как Convert from string по существу разделяет строку на символы и вычитает "0" из каждого из них.

Вместо того, чтобы возиться с вычислениями ASCII, вы можете использовать UInt32.TryParse в качестве альтернативного решения. Однако этот метод требует string вход не char, так что вам придется немного изменить свой подход:

string input = "4000080706200002";

string[] digits = input.Select(x => x.ToString()).ToArray();

foreach(string digit in digits)
{
    uint curDigit = 0;
    if(UInt32.TryParse(digit, out curDigit))
    {
        //arithmetic ops...
    }
    //else failed to parse
}

Вы получаете значения ASCII (или Unicode) для этих символов. Проблема в том, что код указывает на символы '0'... '9' не 0... 9, а 48... 57. Чтобы это исправить, вам нужно отрегулировать это смещение. Например:

curDigit = Convert.ToUInt32(data[i] - '0');

Или же

curDigit = Convert.ToUInt32(data[i] - 48);
Другие вопросы по тегам