如何正确使用cin.peek() [英] How to properly use cin.peek()

查看:130
本文介绍了如何正确使用cin.peek()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该函数应该读取分数并将其放置在数组中。如果用户输入 0,则该功能应退出。我正在尝试使用cin.peek()函数来执行此操作,但是执行总是进入if语句中,并且不允许用户退出。

This function is supposed to read a fraction and place it in an array. If the user enters '0' the function is supposed to exit. I am trying to do this using the cin.peek() function but execution always goes into the if statement and doesn't allow the user to exit.

我应该如何正确编写此代码(我愿意不使用peek(),我认为这是最简单的方法。)

How should I properly code this (I am open to not using peek(), I thought it was the simplest way of doing it.)

谢谢!

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()测试有效:

This test of peek() works however:

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


推荐答案

您的问题有两个使用 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 ')

  1. This function access the next character and does not skip leading whitespace. You probably want to skip leading whitespace before determining what the next character is, e.g., using the manipulator std::ws: (std::cin >> std::ws).peek().
  2. The result from std::istream::peek() is not a char. Instead, it is an std::char_traits<char>::int_type (which is a fancy spelling of int). The result may, e.g., be std::char_traits<char>::eof() and if the value of '0' happens to be negative (I'm not aware of any platform where it is; however, e.g., the funny character from my name 'ü' is a negative value on platforms where char is signed) you wouldn't get the correct result, either. That is, you normally compare the result of std::istream::peek() against the result of std::char_traits<char>::to_int_type(), i.e., you'd use something like this: std::cin.peek() == std::char_traits<char>::to_int_type('0')

也就是说,您的程序不会检查是否可以成功读取提名者和分母,用斜杠分隔。您总是要验证阅读是否成功,例如,使用

That said, your program doesn't check whether it could successfully read the nominator and the denominator, separated by a slash. You always want to verify that reading was successful, e.g., using something like

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

仅出于娱乐目的,您可以创建一个操纵器来测试字符是否为斜线,确实:

Just for entertainment, you can create a manipulator for testing that a character is a slash, indeed:

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

这样,您可以封装斜线测试。如果您需要在多个地方使用它,则非常方便。

This way, you'd encapsulate the test for slash. If you need to use this in multiple places this is quite handy.

这篇关于如何正确使用cin.peek()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆