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
.
解析每一行
此外,您同时使用了 file
和 cin
,并且您的数据仅在文件中,因此您根本不需要使用 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,那么作为一般偏好,您应该 阅读行 ,然后决定如何实际处理它们。
我试过使用 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
.
此外,您同时使用了 file
和 cin
,并且您的数据仅在文件中,因此您根本不需要使用 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,那么作为一般偏好,您应该 阅读行 ,然后决定如何实际处理它们。