Вопрос

Я изучаю C ++ и по ходу дела пишу небольшие программы.Ниже приведена одна из таких программ:

// This program is intended to take any integer and convert to the
// corresponding signed char.

#include <iostream>

int main()
{
  signed char sch = 0;
  int n = 0;
  while(true){
    std::cin >> n;
    sch = n;
    std::cout << n << " --> " << sch << std::endl;
  }
}

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

#: ./int2ch
10
10 --> 

10000000000
10 -->

10 -->

10 -->

10 -->

Программа выдает "10 -->" до тех пор, пока не будет уничтожена.(С этой конкретной последовательностью входных данных скорость вывода программы изменяется неустойчиво.) Я также заметил, что вывод больших значений определяется предыдущим допустимым вводом, а также значением текущего недопустимого ввода.

Что происходит?(Меня не волнует исправление программы, это просто.Я хочу это понять.)

Это было полезно?

Решение

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

#include <iostream>

int main()
{
  signed char sch = 0;
  int n = 0;
  while(std::cin >> n){
    sch = n;
    std::cout << n << " --> " << sch << std::endl;
  }
}

cin >> n вернет ссылку на cin, который вы можете проверить на "исправность" в условном.Так что в основном "while(std::cin >> n)" говорит "пока я все еще могу успешно читать из стандартного ввода, выполните следующее".

Редактировать:причина, по которой он повторно выводит последнее введенное правильное значение, заключается в том, что это было последнее значение, успешно прочитанное в n, неудачные чтения не изменят значение n

Редактировать:как отмечено в комментарии, вы можете очистить состояние ошибки и попробовать еще раз, что-то подобное, вероятно, сработает и просто проигнорирует неверные числа:

#include <iostream>
#include <climits>

int main() {
    signed char sch = 0;
    int n = 0;
    while(true) {
        if(std::cin >> n) {
            sch = n;
            std::cout << n << " --> " << sch << std::endl;
        } else {
            std::cin.clear(); // clear error state
            std::cin.ignore(INT_MAX, '\n'); // ignore this line we couldn't read it
        }
    }
}

Другие советы

Да, Эван Теран уже указал на большинство вещей.Одна вещь, которую я хочу добавить (поскольку я пока не могу прокомментировать его комментарий :)), заключается в том, что вы должны вызвать istream::clear до того , как вызов istream::игнорировать.Причина в том, что istream::ignore аналогично просто откажется что-либо делать, если поток все еще находится в состоянии сбоя.

Учитывая, что вы находитесь на 32-разрядной машине, 10000000000 - это слишком большое число, чтобы быть представленным int.Также преобразование int в char даст вам значение только от 0 ..255 или -128..127 в зависимости от компилятора.

Одна из проблем здесь заключается в том, что char имеет размер в один байт и, следовательно, может содержать только число от -127 до 128.Ан int с другой стороны, обычно он составляет 4 байта и может принимать гораздо большие значения.Вторая проблема заключается в том, что вы вводите значение, которое слишком велико даже для int.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top