Как правильно использовать cin.peek()

Эта функция должна считывать дробь и помещать 9X_peek ее в массив. Если пользователь вводит «0», функция 9X_cxx должна выйти. Я пытаюсь сделать это с помощью 9X_cpp функции cin.peek(), но выполнение всегда 9X_struct переходит в оператор if и не позволяет пользователю 9X_c++ выйти.

Как мне правильно это кодировать (я 9X_struct открыт, чтобы не использовать peek(), я 9X_cpp думал, что это самый простой способ сделать 9X_c++ это.)

Спасибо!

void enterFrac(Fraction* fracs[], int& index) { int n, d; char c, slash; cout << "Enter fractions (end by entering a 0): "; c = cin.peek(); if ( c != '0') { cin >> n >> slash >> d; Fraction* f = new Fraction(); f->num = n; f->den = d; fracs[index] = f; index++; } } 

Однако этот тест peek() работает:

#include using namespace std; int main () { char c; int n; char str[256]; cout << "Enter a number or a word: "; c=cin.peek(); if ( (c >= '0') && (c <= '9') ) { cin >> n; cout << "You have entered number " << n << endl; } else { cin >> str; cout << " You have entered word " << str << endl; } return 0; } 

8
0
1
Общее количество ответов: 1

Ответ #1

Ответ на вопрос: Как правильно использовать cin.peek()

Есть две проблемы с использованием std::istream::peek():

  1. Эта функция обращается к следующему символу и не пропускает начальные пробелы. Вероятно, вы захотите пропустить начальные пробелы перед определением следующего символа, например, используя манипулятор std::ws: (std::cin >> std::ws).peek().
  2. Результат от std::istream::peek() не является char. Вместо этого это std::char_traits::int_type (причудливое написание int). Результатом может быть, например, std::char_traits::eof(), и если значение '0' окажется отрицательным (я не знаю ни одной платформы, где он находится; однако, например, забавный персонаж из моего имени 'ü' является отрицательное значение на платформах, где подписано char), вы также не получите правильный результат. То есть вы обычно сравниваете результат std::istream::peek() с результатом std::char_traits::to_int_type(), т.е. вы должны использовать что-то вроде этого: std::cin.peek() == std::char_traits::to_int_type('0')

При 9X_c++ этом ваша программа не проверяет, может 9X_struct ли она успешно прочитать номинатор и знаменатель, разделенные 9X_c++ косой чертой. Вы всегда хотите убедиться, что 9X_struct чтение было успешным, например, используя 9X_struct что-то вроде

if ((std::cin >> nominator >> slash >> denominator) && slash == '/') { ... } 

Для развлечения вы можете создать 9X_cpp манипулятор для проверки того, действительно 9X_cxx ли персонаж является косой чертой:

std::istream& slash(std::istream& in) { if ((in >> std::ws).peek() != std::char_traits::to_int_type('/')) { in.setstate(std::ios_base::failbit); } return in; } 

Таким 9X_peek образом, вы инкапсулируете тест на косую 9X_cin черту. Если вам нужно использовать это в 9X_peek нескольких местах, это очень удобно.

16
1

  • @Azzi Я думаю, вы попадаете в очень распространенную ловушку, полагая, что `cin >> something` или` cin.peek() `читает следующий вводимый вами символ. Это не так, он читает следующий непрочитанный символ. Как го ...