Как правильно использовать 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