C ++奇怪的cin.ignore行为

时间:2018-12-25 08:59:37

标签: c++

我正在尝试为我的学生构建一个示例应用程序,该应用程序应演示如何使用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;
}

我不太明白我在做什么错

2 个答案:

答案 0 :(得分:0)

cin.ignore()仅忽略一个字符,无论它是否为空格。

我猜您想忽略第一个非白色字符。

例如:

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

并且如评论中所述,getline还将读取行尾。您需要在使用流运算符(>>)之后忽略它,因为它会在行尾之前停止,而第一个getline只会读取新行。

答案 1 :(得分:0)

您需要了解为什么有时有必要使用ignore()!内置的格式化输入运算符(operator>>())使用任何空格字符作为分隔符,不会提取这些分隔符。另一方面,getline()扫描输入以查找换行符的首次出现(默认为’\n’),然后存储并存储并提取所有这些字符。结束时,提取了换行符(您使用的变体形式也有大小限制;我建议将std::string与非成员std::getline()一起使用)。

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

还要确保总是在尝试阅读后验证输入是否成功! inout的绝大多数错误是由于没有检查(如您发布的代码中的情况)或在输入操作之前 进行的。学习事后检查非常重要,以至于“简化代码”的论点不成立:不是简化代码,而是明显的错误!