c++ - 读取和解析文件,将解析后的字符串的每一段分配给它自己的变量

标签 c++ parsing

 89   int Student::loadStudents() {
 90   Student newStudent;
 91   string comma;
 92   string line;
 93   ifstream myfile("student.dat");
 94   string name,email="";
 95   string status="";
 96   int id;
 97   if (myfile.is_open()){
 98     while ( getline (myfile,line) ) {
 99         //parse line
100         string myText(line);
101         istringstream iss(myText);
102         if(!(iss>>id)) id=0;
103
104         std::ignore(1,',');
105         std::getline(iss,name,',');
106         std::getline(iss,status,',');
107         std::getline(iss,email,',');
108         cout<<name<<endl;
109         Student newStudent(id,name,status,email);
110         Student::studentList.insert(std::pair<int,Student>(id,newStudent));

上面是我定义的方法。执行 cout 时,输出为:

李四

马特·史密斯

在我添加第二个 getline(iss,name,',') 之前,cout 什么也没做。

谁能解释为什么它适用于重复的行以及为什么相同的代码不适用于状态和电子邮件?

文件中的示例行:

1,john doe,freshman,jd@email.com

编辑:

我在第一个 getline(iss,name,',') 之前使用了 std::ignore(1,',') 并收到错误 'ignore' is undeclared in this namespace 'std'。

最佳答案

Can anyone explain why it works with the line repeated and why the same code won't work for status and email?

因为你对isa的第一个操作是iss>>id

推测您的输入文件的格式为 id,name,status,email。第一个操作读取到但不包括第一个逗号。第一个逗号仍在输入流中。这意味着您的第一个 std::getline(iss,name,',') 读取第一个逗号和第一个逗号之前剩余的所有内容。第一个逗号之前剩余的所有内容 -- 那是一个空字符串。

最好不要混淆解析概念。沿逗号拆分行,然后解析每个拆分元素。


编辑
处理此问题的另一种方法:调用 std::ignore 而不是第一次调用 std::getline。下一个要读取的字符应该是逗号,所以忽略它。如果您可以假设一个格式正确的输入文件,这是可以的。如果您必须处理由人类创建的变幻莫测的输入文件,那是不行的。

另一个问题:假设某人的名字是“John Doe, PhD”或者电子邮件地址是“John Doe, PhD”?


编辑 2
澄清一下,假设该行包含“1234,John Doe,freshman,jdoe@college_name.edu”。

iss>>id之前的输入指针:
1234,John Doe,新生,jdoe@college_name.edu
^
iss>>id 的调用将 id 设置为 1234 并将输入指针前进到第一个非数字字符 - 第一个逗号。

iss>>id 之后的输入指针(在第一次调用 std::getline 之前):
1234,John Doe,新生,jdoe@college_name.edu
____^
第一个 std::getline(iss,name,',') 看到输入指针位于逗号处。它将 name 设置为空字符串并将输入指针前进到逗号之后。

第一次调用 std::getline 后的输入指针(在第二次调用 std::getline 之前):
1234,John Doe,新生,jdoe@college_name.edu
_____^
第二个 std::getline(iss,name,',') 读取到第二个逗号。它将 name 设置为“John Doe”空字符串并将输入指针前进到第二个逗号之后。

第二次调用 std::getline 后的输入指针(在第三次调用 std::getline 之前):
1234,John Doe,新生,jdoe@college_name.edu
____________^

关于c++ - 读取和解析文件,将解析后的字符串的每一段分配给它自己的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21962459/

相关文章:

c++ - 超过 64 位时的未定义行为

c# - 使用 Anglesharp 从 html 字符串中获取列表 <li> 标签的集合

java - 解析 .txt 文件(考虑性能指标)

java - 无法解析获取无效数组范围 : 5 to 5 的响应

c++ - 取消引用不适用于集合中的智能指针

c++ - 为什么这个递归会产生段错误?

c++ - Qt QTextDocument 新行?

parsing - 通过词法分析确定文本短语的 "Mood"

python-3.x - 如何使用 BeautifulSoup 从表中选择特定行?

c++ - std::sort 中的错误?