Использование cin.get () в тесном цикле - PullRequest
2 голосов
/ 03 сентября 2011

Я не новичок в программировании, но я относительно новичок в C ++.Я хотел бы распространять простые консольные приложения, чтобы я мог помогать другим в процессе обучения.Подавляющее большинство машин в университетском городке моего университета основано на Windows, и по умолчанию установлен компилятор Borland.Я предпочитаю заниматься разработкой под Linux, используя g ++ и другие инструменты.Поэтому я хотел бы добавить кроссплатформенный способ оставить программу работающей, пока пользователь не нажмет ввод.Таким образом, пользователь может просматривать вывод, даже если он или она дважды щелкнули по exe, а не запускали его в консоли в Windows.Для этого я написал что-то похожее на:

#include <iostream>

using namespace std;

int main()
{

    float val1, val2;
    bool wait = true;

    cout << "Please enter the first value to add: ";
    cin >> val1;
    cout << "Please enter the second value to add: ";
    cin >> val2;
    cout << "Result: " << val1 + val2 << endl << endl;

    cout << "Press enter to exit...";

    while (wait)
    {
        if (cin.get() == '\n')
            wait = false;
    }

    return 0;
}

Используя приведенный выше код, программа завершает работу после отображения результата.Однако, если вы закомментируете вызовы cin, все работает как положено.Это наводит меня на мысль, что cin.getline забирает нажатие моей клавиши ввода с моей последней записи данных.Я подозреваю, что это связано с плотностью петли.Я узнал, что в C ++ нет кроссплатформенной функции сна, так что это не вариант.Что еще я могу сделать, чтобы сделать эту работу?

Ответы [ 2 ]

4 голосов
/ 03 сентября 2011

Вы можете добавить

cin.ignore(1);

или

cin.ignore(INT_MAX, '\n');

, прежде чем позвонить cin.get().Это будет игнорировать новую строку слева от пользователя, вводящего второе число или все символы в буфере до новой строки.

Также вам не нужно ни сравнивать возвращаемое значение get с '\n', ни ставить егов петле.Пользователь должен нажать Enter для get, чтобы вернуться, поэтому

cout << "Press enter to exit...";
cin.ignore(INT_MAX, '\n');
cin.get();

Достаточно.

Что произойдет, если вы сделаете

cout << "Press enter to exit...";
while (wait)
{
    if (cin.get() == '\n')
    wait = false;
}

Это то, что цикл введен, и cin.get() вызывается.Пользователь может ввести любое количество текста в консоли, как он хочет.Скажем, они ввели

Hello

в консоли.Затем пользователь нажимает клавишу Enter.cin.get() возвращает H, а ello\n остается в буфере.Вы сравниваете H с \n и видите, что они не равны, продолжаете цикл.cin.get() вызывается, и поскольку в буфере уже есть текст, немедленно возвращается e.Этот цикл продолжает тратить время до тех пор, пока не достигнет последнего символа буфера, равного \n, и сравнивает значение true с \n, поэтому цикл прерывается.Как видите, это пустая трата времени.

Если вы поместите cin.get() в цикл и сравните его возвращаемое значение с \n, существует также опасность того, что cin придетв конец файла до \n.Я полагаю, что влияние этого на вашу программу будет бесконечным циклом, но я не уверен, так как я не могу попробовать это в Windows.

Кроме того, даже если вам не нужно использовать циклво-первых, вы тратите еще больше времени на bool, потому что вы можете уменьшить цикл до

while (true)
    if (cin.get() == '\n') break;
0 голосов
/ 03 сентября 2011

После cin >> вы должны игнорировать все символы в буфере до `\ n 'с

#include <limits> // for std::numeric_limits as indicated by Marlon

std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

Тогда вы можете дождаться следующей строки:

cout << "Press enter to exit...";
cin.get();
...