【问题标题】:C++ weird cin.ignore behaviourC++ 奇怪的 cin.ignore 行为
【发布时间】:2019-05-24 01:18:27
【问题描述】:

我正在尝试为我的学生构建一个示例应用程序,该应用程序应该演示如何使用 cin.getline 和 cin.ignore 输入多个 c 字符串,但我得到了奇怪的结果。在我下面的代码中有两个注释的 cin.ignore 语句。如果我取消注释第一个,则在运行时需要按两次 Enter 输入第一个字符串,只输入第二个字符串。如果我取消注释第二个,那么两个字符串都输入一个 Enter 但第二个字符串不知何故丢失了第一个字母。

#include <iostream>
using namespace std;

struct Unit{
    int uid;
    char* name=new char[50];
    char* shname=new char[10];
};

int main() {
    Unit u;
    cout << "Record number: ";
    cin >> u.uid;
    cout << "Unit name: ";
    cin.ignore();
    cin.getline(u.name,50);
    //cin.ignore();
    cout << "Unit short name: ";
    //cin.ignore();
    cin.getline(u.shname,10);
    cout << "Record number: " << u.uid << endl
         << "Unit name: " << u.name << endl
         << "Unit short name: " << u.shname << endl;
    return 0;
}

我不太明白我做错了什么

【问题讨论】:

标签: c++


【解决方案1】:

您需要了解为什么有时需要使用ignore()!内置格式化输入字符 (operator&gt;&gt;()) 使用任何空格字符作为分隔符,该分隔符提取。另一方面,getline() 扫描输入以查找第一次出现的换行符(默认情况下为 ’\n’),然后存储、存储和提取所有这些字符。它以提取换行符结束(您使用的变体也有大小限制;我建议使用std::string 和非成员std::getline())。

最终效果是,在格式化输入函数之后,缓冲区中的下一个字符是一个分隔空间。当使用标准输入与用户进行交互时,很可能是换行符导致后面的getline() 立即结束。因此,这些空格字符被提取出来是很常见的,最好使用in &gt;&gt; std::ws而不是in.ignore()来处理其他杂散的空格字符。使用getline() 后,通常不需要跳过任何字符,因为换行符已经被提取。换句话说:最好删除评论的ignore()s。

另外,请确保您始终验证输入是否成功尝试读取! inout 的绝大多数错误是由于没有检查(如您发布的代码中的情况)或在输入操作之前检查。学会事后检查非常重要,以至于“使代码简单”的论点不成立:它不是让代码简单,而是完全错误!

【讨论】:

    【解决方案2】:

    cin.ignore() 只忽略一个字符,不管它是否是空格。

    我猜你想在第一个非白色字符之前忽略。

    例如:

    while (iswspace(cin.peek()))
       cin.ignore();
    

    正如评论中所说,getline 也将读取行尾。您需要在使用流运算符 (&gt;&gt;) 后忽略它,因为它会在行尾之前停止,而第一个 getline 将只读取新行。

    【讨论】:

    • cin.ignore(std::numeric_limits&lt;std::streamsize&gt;::max(), '\n');
    • @n.m 取决于,您是要在新行之前忽略有效输入,还是在当前行中获取输入。值前的空格怎么办?你想从空格开始还是在非白色字符的开头?那么长于尺寸的线条呢?没有适用于所有情况的单一答案。
    • 好的,我明白了。如果我使用 getline 读取多个字符串,我不需要使用忽略。只有当我混合 >> 和 getline 调用时,我才需要使用它。谢谢大家的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 2019-04-10
    • 2016-07-15
    • 2011-06-23
    • 2016-08-12
    • 2013-10-28
    相关资源
    最近更新 更多