我想在阅读多个文件之间交替。下面是我的代码的简化版本。
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;
}
现在它就像魅力一样,我可以尽可能多地循环:-)。我很感激你的评论,很高兴知道大哥仍然有帮助。
答案 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;
}