Как правильно использовать 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() `читает следующий вводимый вами символ. Это не так, он читает следующий непрочитанный символ. Как го ...