读取文件:处理行的方式不同

时间:2009-04-05 19:45:25

标签: c++ string file-io

我在尝试用C ++读取文件时遇到了很多麻烦。 我遇到的主要问题是正确读取流的第一行,因为它与所有其他行不同。

示例文件为:

#Newbie 101|Exam 1|3
Person One|10
Person Two|20
Person Three|30

第一行以#开头,并声明类名,assignmanet名和学生总数。

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);

    }

我非常感谢有关如何修复此代码以正确读取文件的任何建议。 非常感谢提前!

3 个答案:

答案 0 :(得分:3)

听起来第一行的读取/解析应该在你的循环之外(上方)。然后,您不必担心在主循环体​​中解析2种不同类型的线。

答案 1 :(得分:0)

您只需要将第一行作为特殊情况单独处理。您可以通过读取主循环外的第一行(当然检查有第一行)或使用布尔值或行计数处理特殊情况的循环内部来完成此操作。

答案 2 :(得分:0)

从我的观点来看,你做错了,你做错了。

LoadData()每次读取“|”时都会读取令牌停止分隔符。 当找到“#Newbie 101”令牌时,它将以#字符开头丢弃它。 它的循环中的下一次迭代它将处理“Exam 1”令牌(下一个......在第一个行!!)。好的。 然后在下一次迭代中,它会读取下一个 “3 \ nPerson one” 。请注意字符串中间的行尾字符! 考虑到输出,我不确定它是你想要的,呵呵?

AFAI明白,您想要的行为是您的程序跳过注释行(以#字符开头)。 作为解决方案,您最好在第一个循环中使用getline(file_handle, line)读取整行。不要指定任何“|”调用getline()时,字符作为第三个参数,'\ n'必须作为分隔符才能获得整个行。

在第一个循环中,添加第一个检查以查看“#”字符是否从该行开始。如果是这样,请调用continue语句。否则输入第二个嵌套循环来解释你的行中的所有标记,这次使用find_first_of()字符串的方法来查找'|'字符。循环,直到你读完整行。

您可以考虑使用BOOST tokeniser lib。虽然我从来没有使用它(或很久以前我曾经使用它),但我记得以一种非常简单的方式完成那种工作是非常合适的! 我相信还有很好的库可以读取文件并丢弃注释行。也许在BOOST ......(这真是一个耻辱我真的需要深入了解这个lib ...)