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

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

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

Спасибо!

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 <iostream>
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;
}

7

Решение

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

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

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

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

Просто для развлечения вы можете создать манипулятор для проверки того, что персонаж — это слеш:

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

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

10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]