c++ getline() 似乎无法正确运行,直到最后才读取该行

c++ getline() doesn't seem to operate correctly, Doesn't read the line till the end

我试过使用 cin.ignore();而不是虚拟变量,没有帮助。文件内容如下所示:

D 姓氏

姓名2姓氏2

...

学生人数未知。

...

输出应如下所示:

名字姓氏class: D

姓名 2 姓氏 2 class: A

但是我的输出是这样的:

姓名Class甲

姓Class小号

姓名2 Class E

姓氏2 Class S ...

代码如下:

#include <iostream>
#include <fstream>
using namespace std;
 
int main() 
{
    ifstream file("students.txt");
    
    if (!file.is_open()) 
    {
        cout << "file can't be opened!" << endl;
        exit(-1);
    }

        char classs;
        string name, dummy;

    while(file >> classs >> name) 
    {
        
      cin.get(classs);
      getline(cin, dummy);
      getline(cin, name);
      
      cout << name << " " << "calass " << classs << endl;
    }
}






您正在使用 getline()>> 从文件流中读取数据,您不应该这样做。这是一个仅使用 >>:

的示例
std::string cls, name, surname;
while(file >> cls >> name >> surname) 
{
    std::cout << name << " " << surname << " class: " << cls << std::endl;
}

我假设文件的每一行都恰好包含三个元素 - class、姓名和姓氏,因为这就是问题中的示例。如果不是这种情况,那么您真的需要使用 getline() 逐行读取文件的内容,然后使用例如 istringstream.

解析每一行

此外,您同时使用了 filecin,并且您的数据仅在文件中,因此您根本不需要使用 cin

看起来您已经尝试了各种方法来完成这项工作,包括在从 file 读取的循环中间从 cin 读取。非常奇怪。我建议你抛出整个循环并尝试如下简单的操作:

您一次只读一行。对于您读取的每一行,您将其放入字符串流中并从中读取值。为了让它更简单,只需读取所有内容的字符串,即使它应该只是一个字符。

// Note: requires <sstream>

string line;
while(getline(file, line))
{
    istringstream iss(line);
    string cls, name, surname;
    if (iss >> cls >> name >> surname)
    {
        cout << name << " " << surname << " class: " << cls << endl;
    }
}

这确实假设总是恰好有两个名字,而您输入的情况似乎并非如此。

作为替代方案,您可以尝试读取单个字符,然后忽略空格,然后读取整行的其余部分:

char cls;
string fullname;
while (getline(file >> cls >> std::ws, fullname))
{
    cout << fullname << " class: " << cls << endl;
}

请注意,上面的内容有点懒惰,因此如果您在文件中遇到空行,这可能会中断。因此,结合 istringstream 方法将是可行的方法:

string line;
while (getline(file, line))
{
    istringstream iss(line);
    char cls;
    string fullname;
    if (iss >> cls >> std::ws >> fullname)
    {
        // Note you may also want to test cls is valid (e.g. isalpha(cls))
        cout << fullname << " class: " << cls << endl;
    }
}

最后,如果您的输入是 line-based,那么作为一般偏好,您应该 阅读行 ,然后决定如何实际处理它们。