如何避免cin.operator>>之间的冲突和getline?

时间:2015-03-22 14:00:40

标签: c++ io

我只想阅读 n ,然后使用getline n 次:

#include <iostream>
using namespace std;

int main() {
    int n;
    cin>>n;
    string film;
    for(int i=0;i<n;i++){
        getline(cin,film);
        cout << film;
    }
}
然而,第一部电影总是变得空洞。 See for yourself。如何让getline容忍默认cin.operator&gt;&gt;在这种情况下?

1 个答案:

答案 0 :(得分:2)

std::cin >> n这样的格式化输入与未格式化的输入(如std::getline(std::cin, film))混合的问题是格式化输入在格式填充且未格式化的输入不会跳过任何空格字符时停止:问题你正在观察的是,n的读取留下了一个换行符,该换行符考虑了第一个字符串的结尾。解决此问题的最佳方法是使用std::ws操纵器跳过所有前导空格。此外,您应始终验证您的输入是否成功。也就是说,你的代码会变成这样:

#include <iostream>
int main() {
    int n;
    if (std::cin >> n) {
        std::string film;
        std::cin >> std::ws; // not really an input, hence uncheckedd
        for (int i(0); i != n && std::getline(std::cin, film); ++i) {
            std::cout << '\'' << film << "'\n";
        }
    }
    else  {
        std::cout << "ERROR: failed to read the number of films\n";
    }
}

如果您确实需要在第一个film的名称中使用前导空格,则需要更加小心忽略空格并停在第一个换行符处。这不是std::cin >> std::ws您使用

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

这个有趣的使用std::numeric_limits(在标题<limits>中声明)确保可以跳过任意数量的空格。你也可以使用一些固定的数字,比如说10,但是在这个数字之后,跳过空格会停止,你仍然可能会清空文件。此外,如果您实际上在与要跳过的文件数相同的行中输入了第一个电影名称。因此,我认为使用std::ws要好得多。