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

How to avoid conflict between cin.operator>> and getline?

我只是想读 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>>?

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

#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 的名称中使用前导白色space,您需要更加小心地忽略白色space 并停在第一个换行符。那不是 std::cin >> std::ws 你会使用

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

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