读取和解析文件,将解析后的字符串的每一部分分配给自己的变量

时间:2014-02-23 00:14:02

标签: 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时输出为:

John Doe

马特史密斯

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

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

来自文件的示例行:

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

编辑:

我在第一个getline(iss,name,',')之前使用了std :: ignore(1,','),并在此命名空间'std'中收到错误'ignore'未声明。

1 个答案:

答案 0 :(得分:3)

  

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

因为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,freshman,jdoe@college_name.edu
^
iss>>id的调用将id设置为1234并将输入指针前进到第一个非数字字符 - 第一个逗号。

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

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

第二次呼叫std::getline后输入指针(在第三次呼叫std::getline之前):
1234,John Doe,freshman,jdoe@college_name.edu
______________^