读取文件:以不同方式处理行
Posted
技术标签:
【中文标题】读取文件:以不同方式处理行【英文标题】:Reading a file: handling lines differently 【发布时间】:2009-04-05 19:45:25 【问题描述】:我在尝试用 C++ 读取文件时遇到了很多麻烦。 我遇到的主要问题是正确读取流的第一行,因为它与所有其他行不同。
一个示例文件是:
#Newbie 101|Exam 1|3
Person One|10
Person Two|20
Person Three|30
第一行以 # 开头并声明班级名称、分配名称和学生总数。
void Grading::loadData()
string filename;
cout << "Enter a filename with records to open: ";
cin >> filename;
std::ifstream file;
file.open(filename.c_str(), std::ios::app);
if (!file)
cout << "Unable to open the specified file" << endl;
return;
string buffer;
vector<Student> students;
vector<Student>::iterator it;
while (!getline(file, buffer, '|').eof())
Student stud;
string name;
string tmpgrade;
string course;
string assignment;
int totalstudents;
// read first line
if (buffer.find("#") == 0)
getline(file, course, '|');
cout << "Course Name : " << course << endl;
cout << "Grading Item : " << assignment << endl;
cout << "Total Students : " << totalstudents << endl;
cout << endl;
continue;
getline(file, name, '|');
getline(file, tmpgrade, '|');
double grade = strtod(tmpgrade.c_str(), NULL);
stud.name = name;
stud.grade = grade;
cout << "Name: " << stud.name << endl;
cout << "Grade: " << stud.grade << endl;
students.push_back(stud);
我非常感谢有关如何修复此代码以正确读取文件的任何建议。 提前非常感谢!
【问题讨论】:
我建议您自己寻找作业的答案。这样你就可以确保你真正学到了一些东西,如果有人发现你在这里得到了答案,你就不会受到惩罚;-) 【参考方案1】:听起来第一行的读取/解析应该在您的循环之外(上方)。然后你就不必担心在你的主循环体中解析 2 种不同类型的行了。
【讨论】:
【参考方案2】:您只需将第一行作为特殊情况单独处理。您可以通过在主循环外部读取第一行(当然检查是否有第一行)或在循环内部处理特殊情况,使用布尔值或行数来做到这一点。
【讨论】:
【参考方案3】:在我看来,你做你想做的事是错误的。
LoadData()
每次读取“|”时都会停止读取令牌分隔符。
当找到 "#Newbie 101" 标记时,它将丢弃它,因为它以 # 字符开头。
其循环中的下一次迭代将处理 "Exam 1" 标记(下一个 .. 在 first 行!!)。好吧。
然后下一次迭代,它读取下一个 "3 \nPerson one"。请注意字符串中间的行尾字符!
考虑到输出,我不确定它是否是您想要的,嗯?
AFAI 明白,您想要的行为是您的程序跳过注释行(以 # 字符开头)。
作为一种解决方案,您最好在第一个循环中使用getline(file_handle, line)
阅读整行。不要指定任何“|”字符作为调用getline()时的第三个参数,必须以'\n'作为分隔符才能得到整行。
在第一个循环中,添加第一个检查以查看“#”字符是否开始该行。如果是这样,请调用 continue 语句。否则进入第二个嵌套循环来解释行中的所有标记,这次使用find_first_of()
字符串的方法来查找“|”特点。循环直到你读完整行。
您可以考虑 BOOST 标记器库。虽然我从未使用过它(或者很久以前当我学习的时候),但我记得以非常简单的方式完成这种工作是非常合适的! 我相信也有很好的库来读取文件并丢弃注释行。也许在 BOOST 中......(很遗憾,我真的必须更深入地了解这个库......)
【讨论】:
快速浏览 Boost 网站,您可以使用 tokeniser 库或字符串库中的 split() 算法来实现您的目标以上是关于读取文件:以不同方式处理行的主要内容,如果未能解决你的问题,请参考以下文章