Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

C++. Программа пропускает строчку кода(считывание переменной)

#cpp #потоки_данных #вектор


Доброго времени суток.
Возникла проблема с С++. Если кратко - в одной строчке не происходит считывание с
помощью потока ввода cin.
Код ниже. Место где происходит ошибка - обозначено комментарием. Пробовал очищать
поток перед считыванием user_num_to_sum с помощью cin.clear() - don't help.

#include  //cin, cout
#include  //_getch()
#include  //vector

using std::cout;
using std::cin;
using std::vector;


int main () {
    vector numbers; // вектор из целых чисел
    int num = 0; // число которое заносим в конец вектора
    int user_num_to_sum = 0; // число элементов вектора для суммирования(пример:
если число 3, то суммируем первые 3 элемента)

    cout << "Write a few numbers: \n";
    while(cin >> num) {
        numbers.push_back(num);// заносим числа в вектор
        }
    cout << "How much elements of vector do you want to sum?\n";
    cin >> user_num_to_sum; // ERROR: программа пропускает данную строчку и выполняет
следующую подставляя в user_num_to_sum значение 0, которое было задано при инициализации.
    cout << "The sum of first " << user_num_to_sum << " numbers -> ";

//код еще не готов полностью, программа смысла не имеет

    _getch();

    return 0;
}


Я и останавливаю цикл while(cin >> num) вводом ошибочного символа '|'. Данный приём
использует в своей книге Страуструп. Вот только потом почему-то после остановки цикла
не срабатывает считывание целого числа user_num_to_sum.

P.S. Сработал вариант с использованием cin.clear(), но только в случае завершения
ввода данных в вектор путём нажатия Ctrl+Z. 
Если же завершить его путём ввода неверных данных(к примеру '|' при считывании данных
типа int), то cin.clear() не срабатывает. Вопрос: почему?
    


Ответы

Ответ 1



while(cin >> num) { // Пока мы можем прочитать int, читаем его ... // и что-то делаем } // Вышли из цикла, т. к. int прочитать нельзя ... // Тут мы ничего не читали cin >> user_num_to_sum; // Опа! Чиатем ещё int Но ведь состояние потока не изменилось - int как нельзя было прочитать, так и сейчас нельзя. Если ввод последовательности чисел заканчивается неким нечисловым вводом, следует прочитать это нечто как строку и только потом считывать следующее число. Если же ввод завершался нажатием ctrl+z, то там вроде вообще eof выставляется. Также для сброса маркера ошибки надо перед чтением вызвать cin.clear().

Ответ 2



while(cin >> num) { numbers.push_back(num);// заносим числа в вектор } std::string s; cin.clear(); // сбрасываем ошибку в cin cin >> s; // убираем из cin нечисловые символы cout << "How much elements of vector do you want to sum?\n"; cin >> user_num_to_sum; // ERROR: программа пропускает данную строчку и выполняет следующую подставляя в user_num_to_sum значение 0, которое было задано при инициализации. Вот так Ваш код будет работать корректно при завершении заполнения вектора любым нечисловым символом. Собственно, ответ на последний вопрос: cin.clear() сбрасывает флаги (состояние) ошибки в потоке, но последний введенный символ (группа символов) в нем остается, поэтому их нужно оттуда убрать, например в какую-то ненужную строку. П.С. Вопрос получился неожиданно интересным и заслуживает поощрения в виде плюса. П.П.С. Нашелся вариант без лишней переменной (проверил, нужно #include ) cout << "Write a few numbers (end with any non-number input): \n"; while(cin >> num) { numbers.push_back(num);// заносим числа в вектор } cin.clear(); // сбрасываем флаг ошибки cin.ignore(std::numeric_limits::max(), '\n'); // пропускаем все до символа новой строки cout << "How much elements of vector do you want to sum?\n"; cin >> user_num_to_sum;

Комментариев нет:

Отправить комментарий