нельзя использовать cin дважды, также cin.clear и cin.ignore не работают

Я новичок в программировании на C++ и столкнулся с проблемой. Вот мой код:

#include <iostream>
using namespace std;

int main(){

    int sum = 0, a;
    cout << "enter first set of numbers:";
    while(cin >> a) sum += a;
    cout << "first sum = " << sum;
    cin.clear();
    cin.ignore( numeric_limits<streamsize>::max(), '\n');

    sum = 0;
    cout << "enter second set of numbers:";
    while(cin >> a) sum += a;
    cout << "second sum = " << sum;
}

Я пытаюсь суммировать два набора чисел, которые я ввожу в командной строке. Проблема в том, что когда я нажимаю ctrl-d для завершения первого набора чисел, он пропускает второй набор cin. Большинство страниц, которые я нахожу в Интернете, советуют использовать cin.clear и cin.ignore. Я пробовал это, и это все еще не работает. На этой странице вопрос, касающийся cin.clear(), даже похоже, есть те же проблемы. Тем не менее, исправления, которые они предлагают, не работают для меня.

Этот код выше работает для кого-то еще?


person xdavidliu    schedule 14.11.2013    source источник


Ответы (3)


Когда вы используете Ctrl-D, вы завершаете входной поток: больше нет символов, исходящих из std::cin. Даже очистка потока не помогает: вы сказали потоку, что он в конце. Вы не можете снова открыть его. Однако clear()обработка потока и использование ignore() — это решение вашей проблемы!

Вам нужен другой индикатор того, что один набор значений выполнен. Проще всего использовать нецифровой символ или строку: попытка прочитать что-то, что не является int, приведет к тому, что поток перейдет в режим сбоя [без закрытия потока]. То есть вы читаете до тех пор, пока преобразование не завершится, clear() поток, и ignore() все до конца строки.

Ваш код уже должен это делать: вместо использования Ctrl-D просто введите, например, x.

person Dietmar Kühl    schedule 14.11.2013
comment
Хорошо, завершение с помощью символа вместо ctrl-d работает; большое спасибо. Мне просто интересно, почему в главе 4 книги Accelerated C++ предполагается, что не только ctrl-d будет нормально работать для нескольких блоков cin, но и что мне нужен только cin.clear, а не оба cin.ignore? - person xdavidliu; 14.11.2013
comment
@ user2990344: Я думаю, вам нужно избавиться от оскорбительного персонажа, то есть вам понадобится std::cin.ignore(). Как они пришли к выводу, что Ctrl-D должен работать, я не знаю. Мне это кажется странным, поскольку Эндрю, безусловно, знает лучше. - person Dietmar Kühl; 14.11.2013
comment
@xdavidliu Это поведение отличается в macOS и Linux. В stackoverflow есть безумное количество дезинформации об этом, но из того, что я могу сказать (хотя я не эксперт): пример отлично работал бы в Linux, но в macOS вам также нужно снова открыть stdin. - person Brennan Vincent; 01.05.2019

//Используем stringstream ^^ для множественного пользовательского ввода

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main (void)
{
    string mystr;
    float price = 0;
    int quantity = 0;

    cout << "Enter price: ";
    getline (cin, mystr);
    stringstream(mystr) >> price;
    cout << "Enter quantity:";
    getline (cin, mystr);
    stringstream(mystr) >> quantity;
    cout << "Total price: " << price*quantity << endl;

    return 0;

}
person JMC    schedule 15.11.2016

Вы можете использовать Ctrl-D, вам просто нужно, чтобы ваш цикл был в другом потоке. Итак, Ctrl-D убивает поток, затем возвращается к вашей основной функции, после чего вы можете запустить другой поток. Это не лучшее решение, но оно может сработать, http://codebase.eu/tutorial/posix-threads-c/

person Aage Torleif    schedule 14.11.2013