Console.ReadLine добавить 48 к int - PullRequest
       17

Console.ReadLine добавить 48 к int

2 голосов
/ 06 февраля 2012

Я получаю 48 при вводе 0 в ReadLine ().

Это ошибка?

class Program
{
    static void Main(string[] args)
    {
        string name;
        int age;

        readPerson(out name, out age);
    }
    static void readPerson(out string name, out int age)
    {
        Console.Write("Enter name: ");
        name = Console.ReadLine();
        Console.Write("Enter age: ");
        age = Console.Read();
        Console.WriteLine("Name: {0}; Age: {1}", name, age.ToString());
    }
}

Ответы [ 3 ]

9 голосов
/ 06 февраля 2012

Нет, это совсем не ошибка.

Console.Read() возвращает код символа ASCII для любого введенного символа.Код ASCII для цифры 0 - 48, для цифры 1 - 49 и т. Д.Он не добавляет число 48 произвольно и не имеет ничего общего с out параметрами.

Вам нужно прочитать строку и соответственно преобразовать входные данные в целое число:

Console.Write("Enter age: ");
age = Convert.ToInt32(Console.ReadLine());

Если по какой-либо причине вам нужно использовать Read(), то, как я сказал в своем комментарии, вам нужно привести результат к char.Вам также нужно изменить переменную с int age на char age:

class Program
{
    static void Main(string[] args)
    {
        string name;
        char age;

        readPerson(out name, out age);
    }
    static void readPerson(out string name, out char age)
    {
        Console.Write("Enter name: ");
        name = Console.ReadLine();
        Console.Write("Enter age: ");
        age = (char) Console.Read();
        Console.WriteLine("Name: {0}; Age: {1}", name, age.ToString());
    }
}

Помните, что Read() может читать только один символ за раз, поэтому, если вам нужно проанализироватьЕсли у вас несколько цифр, это не сработает, и вам гораздо лучше просто использовать ReadLine().

7 голосов
/ 06 февраля 2012

Согласно документации MSDN, метод Console.Read возвращает:

Следующий символ из входного потока или отрицательный (-1), если в данный момент больше нет символов для чтения.

Итак, на самом деле вы видите только первый символ, который в данный момент находится в потоке (то есть символы, полученные между двумя последними Enter pushes).

Во время вашего модульного тестирования казалось, что значения были сдвинуты на 48, потому что так получилось, что значения ASCII для символов от «0» до «9», как вы уже догадались, 48 для «0», 49 для «1» и т. Д .:

ASCII Table

Поскольку вы не указали преобразование, содержимое потока «автоматически» считывалось как char значения, а ваш вызов Read() отображал их десятичные эквиваленты ASCII.

Вы можете проверить это с помощью этого простого теста:

static void TestRead()
{
    int current = 0;

    Console.Write("Enter 1: ");
    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    Console.Write("Enter 22: ");
    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);
}

Что приведет к:

Output

Вы заметите, что параллельные вызовы Read() захватывают один символ из потока и дают его десятичный эквивалент ASCII. Также обратите внимание на то, как Windows добавляет последовательность возврата каретки (ASCII 13) и перевода строки (ASCII 10) для каждого нажатия клавиши Enter , которое ваша программа точно возвращает вам.

Небольшая модификация этого метода тестирования поможет определить точку, в которой отсутствуют конкретные направления, среда выполнения будет интерпретировать содержимое вашего входного потока в виде символов:

static void TestReadModified()
{
    int current = 0;

    Console.Write("Enter a: ");
    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);
}

Как и ожидалось, приведенный выше метод вернет значение ASCII для символа 'a':

Output for a letter

Как уже упоминали другие, это легко исправить. Просто сообщите среде выполнения, что вы хотите, чтобы значение интерпретировалось как int. Вероятно, это также хорошая идея, по крайней мере, проверить, что полученный вход является числом:

static void readPerson(out string name, out int age)
{
    Console.Write("Enter name: ");
    name = Console.ReadLine();

    Console.Write("Enter age: ");

    // in this case, we could simply use tempAge (defaults to 0)
    // but it's just practice to check TryParse's success flag
    int tempAge;
    var success = Int32.TryParse(Console.ReadLine(), out tempAge);

    age = success ? tempAge : 0;

    Console.WriteLine("Name: {0}; Age: {1}", name, age);
    Console.ReadLine();
}
1 голос
/ 06 февраля 2012

ASCII-коды для номеров печатаются.Обратите внимание, что Console.Read() читает следующий символ из стандартного ввода и возвращает int.Таким образом, когда вы вводите символ 0 (не целое число 0), он возвращает код ASCII 48 и так далее.Кроме того, этот ASCII-код является целочисленным кодом для символа (скажем, 0), поэтому преобразование в int этого кода является избыточным.Вы читаете в возрасте как строку и конвертируете ее в целое число, что можно сделать с помощью Console.ReadLine и затем с помощью int.TryParse и т. Д.

...