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

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() 算法来实现您的目标

以上是关于读取文件:以不同方式处理行的主要内容,如果未能解决你的问题,请参考以下文章

如何在骆驼中将文件拆分为行但以不同方式处理第一行

最有效的文件读取方式

用python实现读写文件常见操作方式

04 pandas DataFrame_创建、文件读取、编码

如何读取具有不同数字行数的文件

C语言数据读取