我有一个文本文件,如下所示:
Name_of_st1 67 5 87 4 78 4
Name_of_st2 89 5 56 3 79 4
...
我编写了一个程序来读取数据并创建一个具有自己的主题向量的学生向量。程序正确读取第一行,但当我要求它写出第二个学生的名字时,std::cout
显示垃圾。这是代码:
struct Subject {
int mark0;
int mark1;
};
struct Student {
char name[50];
char surname[50];
vector<Subject>my_marks;
};
istream& operator>>(istream& is, Subject& sub);
istream& operator>>(istream& is, Student& st);
int main()
try
{
ifstream ifs("Text.txt");
vector<Student>group;
Student s1, s2;
ifs >> s1;
group.push_back(s1);
getline(ifs, temp);
ifs >> s2;
group.push_back(s2);
cout << group.size();
cout << group[0].name;
cout << group[0].surname;
cout << group[1].name;
cout << group[0].my_marks[1].mark0;
}
catch (exception& e){
cerr << e.what() << endl;
return 1;
}
catch (...)
{
cerr << "exception \n";
return 2;
}
istream& operator>>(istream& is, Subject& sub)
{
int m0, m1;
is >> m0;
if (!is) return is;
is>> m1;
sub.mark0 = m0;
sub.mark1 = m1;
return is;
}
istream& operator>>(istream& is, Student& st)
{
char n1[50];
char n2[50];
is >> n1;
is >> n2;
strcpy_s(st.name, n1);
strcpy_s(st.surname, n2);
if (!is) return is;
while (true)
{
Subject sub;
if (!(is >> sub)) break;
st.my_marks.push_back(sub);
}
return is;
}
我试过这个,但仍然一样:
string temp
ifs >> s1;
getline(ifs, temp);
group.push_back(s1);
而且:
char n1[50];
char n2[50];
for (int i = 0;; ++i)
{
char n0;
is.get(n0);
if (isspace(n0)) break;
n1[i] = n0;
}
for (int i = 0;; ++i)
{
char n0;
is.get(n0);
if (isspace(n0)) break;
n2[i] = n0;
}
if (!is) return is;
strcpy_s(st.name, n1);
strcpy_s(st.surname, n2);
然后我在每个学生姓名后添加':'
并使用is.get(n1, 100, ':')
。
它仍然正确读取第一行,但拒绝阅读下一行。无论我做了什么,我都不能将文本光标移动到新行的开头。如果有人可以帮助我,我会很感激。
答案 0 :(得分:2)
您的第二个学生没有被阅读,因为您在第一个学生的阅读状态不佳时就读了。
if (!(is >> sub)) break;
你基本上阅读主题,直到输入中断(这是你命名的时候)。由于您没有将流的状态重置为good
,因此将忽略任何进一步的读取尝试。
你有两个选择。
阅读完主题后,将状态设置为良好 这有一个问题,你可能会进入无限循环,因为你当前检查流状态是不稳定的。
读取一行,然后从该行解析主题信息。
我会选择2。
// After you have read the name.
// The rest of the line is scores. So read a whole line.
std::string line;
std::getline(is, line);
// convert the line into a stream.
std::stringstream linestream(line);
// Now parse the stream for subject.
Subject sub;
while(linestream >> sub) { // Note this reads an item and checks the
// state of the stream. The while body
// is only entered on a successful read.
st.my_marks.push_back(sub);
}