【问题标题】:How to use correctly the return value from std::cin.get() and std::cin.peek()?如何正确使用 std::cin.get() 和 std::cin.peek() 的返回值?
【发布时间】:2021-02-15 01:30:46
【问题描述】:

我一直这样使用peek(), get()

int main(){

    std::string str;
    int value{};
    if(std::isdigit(std::cin.peek()))
       std::cin >> value;
    else
       std::getline(cin, str);

    std::cout << "value : " << value << '\n';
    std::cout << "str: " << str << '\n';

}

还有很多 C++ 网站和论坛使用这样的东西:

while(std::cin.peek() != '\n)
    ; do somthing
  • 但是在阅读了关于 C++ 入门的注释后,我感到很困惑。据说那些函数get(), peek()返回一个int而不是char所以我们不能将结果分配给一个char,而是一个int

  • 据说那里的字符首先转换为unsigned char,然后提升为int

那么我该如何正确使用这些功能呢?

【问题讨论】:

  • 在内部,peek 调用char_traits&lt;char&gt;::to_int_type 将从流中读取的char 值转换为int。人们一直在编写像你这样的代码,但令我惊讶的是,我无法在标准中找到保证to_int_type('\n') == int('\n') 的要求,例如。我真诚地希望我是错的——当然我不想每次都写using Traits = std::char_traits&lt;char&gt;; Traits::eq_int_type(std::cin.peek(), Traits::to_int_type('\n'))
  • 原始代码很差,因为它在一个分支中消耗了整行,在另一个分支中消耗了部分行,因此无法正确输入下一段
  • @L.F.:你的评论很有用。请添加答案。

标签: c++ iostream peek


【解决方案1】:

所以我们不能将结果赋值给 char 而是赋值给 int

while(std::cin.peek() != '\n') 没有将peek() 的结果分配给字符。它正在比较一个char和一个int。这里 char 被隐式​​转换为 int 然后进行比较。感谢@M.M,这样使用更安全:while(std::cin.good() &amp;&amp; std::cin.peek() != '\n')

https://www.learncpp.com/cpp-tutorial/implicit-type-conversion-coercion/

【讨论】:

  • 用法不好,如果输入有错误会无限循环
  • 这没什么区别“它只是比较一个 char 和一个 int”,因为在这两种情况下,比较或分配给的字符都将提升为 int
  • 如果“很好”,那么为什么peek()get() 返回int 而不是char?标准库的实现者足够聪明,因为没有办法从这些函数返回文件结尾作为字符。因为它的值超出了字符范围。将超出 char 范围的值分配给有符号 char 会导致 Singed Char 溢出,这是未定义的行为。
  • @M.M:你能解释一下吗?
  • @Maestro 如果调用返回 EOF,循环将如何结束?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
  • 2022-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
相关资源
最近更新 更多