读取多个文件

时间:2011-06-10 08:32:23

标签: c++ ifstream

我想在阅读多个文件之间交替。下面是我的代码的简化版本。

ifstream* In_file1 = new ifstream("a.dat",  ios::binary);
ifstream* In_file2 = new ifstream("b..dat",  ios::binary);
ifstream* In_file;
int ID;

In_file = In_file1; 
int ID = 0;

//LOOPING PORTION
if (In_file -> eof())
{
  In_file -> seekg(0, ios_base::beg);
  In_file->close();

  switch (ID)
   {
     case 0:
           In_file = In_file2;  ID = 1; break;
     case 1:
          In_file = In_file1; ID = 0;  break;
   }
}
//some codes
:
:
In_file->read (data, sizeof(double));

//LOOPING PORTION

如果我一次读取文件,代码效果很好,我认为一切都很酷。但是,如果称为“循环部分”的部分位于循环内,则行为变得奇怪并且我开始具有单个重复输出。请问有人可以告诉我出了什么问题以及如何解决这个问题?如果您有更好的方法来解决问题,请建议。我很感激。

//解决

感谢大家的评论,我很感激。这就是我简单的做法:

而不是原来的

switch (ID)
{
  case 0:
   In_file = In_file2;  ID = 1; break;
   case 1:
   In_file = In_file1; ID = 0;  break;
}

我只是做了

switch (ID)
{
  case 0:
   In_file = new ifstream("a.dat",  ios::binary);  ID = 1; break;
  case 1:
  In_file = new ifstream("b.dat",  ios::binary);  ID = 0;  break;
}

现在它就像魅力一样,我可以尽可能多地循环:-)。我很感激你的评论,很高兴知道大哥仍然有帮助。

2 个答案:

答案 0 :(得分:4)

让我们看看:您发布的代码工作正常,您希望我们告诉您 您没有发布的代码有什么问题。这很难。

但是,您发布的代码可能也无法正常工作。 std::istream::eof只能在输入后可靠地使用(或者一些 其他操作)失败了;在您发布的代码中,它几乎就会出现 无论如何,肯定是假的。

此外:无需动态分配ifstream;在 事实上,几乎没有动态分配ifstream的情况 是合适的。而且你没有检查打开是否成功。

如果你想一个接一个地读取两个文件,最简单的方法是 使用两个循环,一个接一个(调用一个常用的函数) 处理数据)。如果由于某种原因这不合适,我会 使用自定义streambuf,它获取文件名列表 构造函数,并在它到达文件末尾时前进到下一个 一,只有当它到达所有的结尾时才返回EOF 文件。 (这样做的唯一复杂因素是,如果其中一个,该怎么做 open失败了。我经常这样做,这是我的工具包的一部分, 我使用回调来处理失败。但是,一次性使用 你可以在任何合适的地方硬编码。)

作为一个简单的例子:

//  We define our own streambuf, deriving from std::streambuf
//  (All istream and ostream delegate to a streambuf for the
//  actual data transfer; we'll use an instance of this to
//  initialize the istream we're going to read from.)
class MultiFileInputStreambuf : public std::streambuf
{
    //  The list of files we will process
    std::vector<std::string> m_filenames;
    //  And our current position in the list (actually
    //  one past the current position, since we increment
    //  it when we open the file).
    std::vector<std::string>::const_iterator m_current;

    //  Rather than create a new filebuf for each file, we'll
    //  reuse this one, closing any previously open file, and
    //  opening a new file, as needed.
    std::filebuf m_streambuf;

protected:
    //  This is part of the protocol for streambuf.  The base
    //  class will call this function anytime it needs to
    //  get a character, and there aren't any in the buffer.
    //  This function can set up a buffer, if it wants, but
    //  in this case, the buffering is handled by the filebuf,
    //  so it's likely not worth the bother.  (But this depends
    //  on the cost of virtual functions---without a buffer,
    //  each character read will require a virtual function call
    //  to get here.
    //
    //  The protocol is to return the next character, or EOF if
    //  there isn't one.
    virtual int underflow()
    {
        //  Get one character from the current streambuf.
        int result = m_streambuf.sgetc();
        //  As long as 1) the current streambuf is at end of file,
        //  and 2) there are more files to read, open the next file
        //  and try to get a character from it.
        while ( result == EOF && m_current != m_filenames.eof() ) {
            m_streambuf.close();
            m_streambuf.open( m_current->c_str(), std::ios::in );
            if ( !m_streambuf.is_open() )
                //  Error handling here...
            ++ m_current;
            result = m_streambuf.sgetc();
        }
        //  We've either gotten a character from the (now) current
        //  streambuf, or there are no more files, and we'll return
        //  the EOF from our last attempt at reading.
        return result;
    }

public:
    //  Use a template and two iterators to initialize the list
    //  of files from any STL sequence whose elements can be
    //  implicitly converted to std::string.
    template<typename ForwardIterator>
    MultiFileInputStreambuf(ForwardIterator begin, ForwardIterator end)
        : m_filenames(begin, end)
        , m_current(m_filenames.begin())
    {
    }
};

答案 1 :(得分:0)

#include <iostream>
#include <fstream>
#include <string>

#define NO_OF_FILES 2

int main () 
{
  std::ifstream in;
  std::string line;
  std::string files[NO_OF_FILES] = 
  {
    "file1.txt", 
    "file2.txt",
  };
  // start our engine!
  for (int i = 0; i < NO_OF_FILES; i++)
  {
    in.open(files[i].c_str(), std::fstream::in);
    if (in.is_open())
    {
      std::cout << "reading... " << files[i] << endl;
      while (in.good())
      {
        getline(in, line);
        std::cout << line << std::endl;
      }
      in.close();
      std::cout << "SUCCESS" << std::endl;
    }
    else
      std::cout << "Error: unable to open " + files[i] << std::endl;
  }

  return 0;
}