ifstream和ofstream:如何对文件执行多项修改?

时间:2017-02-15 16:19:06

标签: c++ parsing fstream

我一直在谷歌搜索这个问题几个小时,似乎无法找到解决它的任何问题。

我对C ++中的文件操作非常朦胧,但我花了大约20年的时间阅读文档和论坛问题,试图为朋友一起制作一个项目。

假设我有一个名为raw_questions.txt的文件,我想对它进行一些更改。此文件是考试的学习指南,有一个问题,后面跟着4个多项选择答案。我想删除空行并添加一些令牌以允许我正在处理的另一个程序来解析它。我编写了一个格式化程序来执行这些操作。操作是:

  1. 从源文件中删除空白行,因为它显示为双倍行距
  2. 在每个问题的末尾添加分隔符('@') 答案。
  3. 使用分隔符,阅读每个问题并以字符串形式回答 并将其附加到输出文件的开头有一个标记 问题或答案,这将让我的其他程序知道是否 line包含问题或答案。
  4. 我的问题:我一直坚持如何从一个操作转移到下一个操作。我目前的方法是将每一行读入一个字符串,对该字符串执行操作,并将新字符串添加到输出文件中。使用这种方法,为了执行下一个操作,我必须打开上一个操作的输出文件作为我的新输入文件,并为该操作创建一个新的输出文件。我觉得必须有更好的方法,但就像我说的那样,我对C ++中的文件操作非常朦胧。在这种情况下我该怎么做?

    我考虑创建一个ifstream和ofstream,它们都指向同一个文件,并希望当ifstream文件打开时,它会在内存中存储一​​个临时副本。然后,在我逐行读取并写入我的ofstream对象后,当它关闭时,它将覆盖我的旧文件。我不知道这是否有意义,我认为这甚至不是fstream如何运作。

    到目前为止我的代码:

    #include <fstream>
    #include <string>
    #include "Debug.h"
    
    Debug debugger;
    
    void remove_empty_lines (std::ifstream& input, std::ofstream& output);
    void insert_delimiter (std::ifstream& input, std::ofstream& output, char delimiter);
    void create_output (std::ifstream& input, std::ofstream& output);
    
    int main() {
        debugger.set_active();
    
        char delimiter = '@';
    
        std::ifstream input;
        std::ofstream output;
        input.open("questions_source.txt");
        output.open("questions_intermidiate.txt");
    
        remove_empty_lines (input, output);
    
    }
    
    void remove_empty_lines (std::ifstream& input, std::ofstream& output) {
        while (!input.eof()) {
            std::string line;
    
            std::getline(input, line);
            if (line != "") {
                output << line << std::endl;
            }
        }
    }
    
    void insert_delimiter(std::ifstream& input, std::ofstream& output) {
    }
    
    // This function doesn't quite work, WIP - Please ignore
    void create_output(std::ifstream& input, std::ofstream& output) {
        std::string line;
    
        for (int i = 1; !input.eof(); i++) {
            debugger.out("Inserting tokens.");
            bool found = false;
            while (!found) {
                getline (input, line);
                if (i < 10) {
                    if (line[1] == ')') {
                        line.erase (0, 3);
                        output << "[" << i << "]" << line << std::endl;
                        debugger.out("Found line: " + line);
                        found = true;
                    }
                } else if (i < 100) {
                    if (line[2] == ')') {
                        line.erase (0, 4);
                        output << "[" << i << "]" << line << std::endl;
                        debugger.out("Found line: " + line);
                        found = true;
                    }
                }
            }
    
            for (int j = 0; j < 4; j++) {
                getline (input, line);
                if (line[1] == ')') {
                    line.erase (0, 3);
                    output << "[" << i << "a]" << line << std::endl;
                }
            }
    
        }
    }
    

    我现在也在尝试自学git,所以我碰巧在github here上托管了我正在进行的项目。我不知道上下文是否会使我想要做的事情有意义,但我发布它是为了以防万一。

    奖金问题:我一直绞尽脑汁,但我没有提出添加分隔符的解决方案。答案似乎是一行长,所以我可能只是将分隔符添加到以“A)”开头的任何行的末尾,但有些问题要长得多。我的想法是找到任何“A)”的出现,并将分隔符添加到它上面的行的末尾,但我想不出怎么做。任何人都可以指出我可能有帮助的fstream成员函数的正确方向吗?

    感谢阅读。

1 个答案:

答案 0 :(得分:1)

Streams不会将整个文件神奇地读入内存。如果这是你想要做的,你应该这样做:我的猜测是你的文件比你的可用内存小得多,并且使用标准C ++容器执行所有操作可能更容易。