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'未声明。
答案 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
______________^