Как правильно использовать 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; }
Ответ #1
Ответ на вопрос: Как правильно использовать cin.peek()
Есть две проблемы с использованием std::istream::peek()
:
- Эта функция обращается к следующему символу и не пропускает начальные пробелы. Вероятно, вы захотите пропустить начальные пробелы перед определением следующего символа, например, используя манипулятор
std::ws
:(std::cin >> std::ws).peek()
. - Результат от
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 нескольких местах, это очень удобно.
- @Azzi Я думаю, вы попадаете в очень распространенную ловушку, полагая, что `cin >> something` или` cin.peek() `читает следующий вводимый вами символ. Это не так, он читает следующий непрочитанный символ. Как го ...
-
5
-
2
-
3
-
16
-
8
-
4
-
5
-
5
-
4
-
5
-
3
-
8
-
1
-
12
-
6
-
3
-
3
-
7
-
3
-
5
-
2
-
2
-
4
-
5
-
2
-
9
-
8
-
4
-
8
-
3
-
4
-
2
-
5
-
3
-
18
-
4
-
4
-
6
-
3
-
5
-
2
-
4
-
3
-
1
-
5
-
6
-
1
-
4
-
3
-
3