【问题标题】:Reading and maintaining a stack of input streams读取和维护一堆输入流
【发布时间】:2017-03-30 02:26:52
【问题描述】:

所以我试图创建一个循环,通过文件读取行并根据该行执行操作,除了某些行可以是另一个文件名,我需要打开并开始从该文件读取,同时保持堆栈上的原始文件,这可能会发生多次,当新文件是 EOF 时,我需要从堆栈中弹回上一个文件。

    std::ifstream* currentStream = fileStream;
    // this is within a class where I pass through fileStream in its initialization
    stack<std::ifstream*> fileStack = stack<std::ifstream*>();

    while(!fileStack.empty() || !currentStream->eof()){
      while (!currentStream->eof()) {
        getline(*currentStream, lineBuf);
        string line = trim(lineBuf);  
        if (line = blahblah) {
          //do stuff
        }
        else if (words[0] == "file") {
          auto params = extractParameters(line);
          std::ifstream simpFileStream;
          simpFileStream.open(params[1][0].substr(1, params[1][0].length()-2) + ".simp");
          currentStream->swap(simpFileStream);
          fileStack.push(&simpFileStream);
        }
        if(!fileStack.empty() && currentStream->eof()){
          // what to do here?
          fileStack.pop();
        }
      }
    }

在我的代码中,我尝试了几种方法,但这是我上次保存的方法,我基本上创建了一个新的 ifstream 并交换当前的并尝试将旧的推入堆栈,我不确定如果这甚至可以正常工作。

在我的 if 语句中,我尝试了一些方法,但似乎没有任何效果,所以这就是我遇到问题的地方。基本上,当我测试我的代码时,打开一个新流就可以了,它开始读入新文件,但我不完全确定如何弹回旧的 ifstream。

【问题讨论】:

  • 您可以使用以文件名作为参数的递归函数。在函数中,您打开文件并逐行读取。读入文件名时,调用该文件名的函数。
  • 你做错了几乎所有事情。您正在循环播放eof。您正在将超出范围的流的地址推送到您的堆栈中。您正在重用从文件流中移出的文件...也不清楚程序应该做什么,因此很难提出建议。
  • 你说得对,我做了很多更改并删除了一些东西以使其正常工作。我想我真正的问题是是否有办法将文件流正确保存到堆栈中以便稍后弹出。
  • 也许您可以将您的问题编辑得更简洁。我试图遵循您的逻辑,但无法看到您要做什么。将新文件流推送到堆栈后,您会立即再次将其取出...?
  • 我为这个凌乱的问题道歉。它从堆栈中弹出的部分意味着如果文件为空并且我想从堆栈顶部获取上一个文件,然后将其从堆栈中弹出。

标签: c++ stack ifstream


【解决方案1】:

从您的 cmets 看来,您可能正在寻找一个有点像这样的结构:

void method(std::string const& filename)
{
    // use smart pointers to avoid memory leaks
    std::stack<std::unique_ptr<std::ifstream>> files;

    // open initial file and push it to the top of the stack
    // to use as the 'current' file
    files.push(std::make_unique<std::ifstream>(filename));

    // use the top() of the stack as your 'current' file stream

    // as long as we have open files, keep going
    while(!files.empty())
    {
        // read the line in the loop control block
        for(std::string line; std::getline(*files.top(), line);)
        {
            if(line == "some stuff")
            {
                // start a new file on the top of the stack
                files.push(std::make_unique<std::ifstream>("new file name"));
            }
            else if(line == "some other stuff")
            {
                // do other stuff
            }
            // yet more stuff
        }

        // end of file reached here - pop
        // delete the current file stream off the top
        // of the stack (automatically closing the file)
        files.pop();
        // Now the top of the stack contains the previous current file stream
    }
}

【讨论】:

  • 谢谢,这个结构正是我想要的。
猜你喜欢
  • 2023-04-04
  • 2020-07-29
  • 2018-04-21
  • 1970-01-01
  • 2018-01-08
  • 2022-01-11
  • 2014-12-04
  • 2011-02-12
相关资源
最近更新 更多