How do I create an array of ifstream objects and h

2019-02-14 20:57发布

I have a bunch of text files in a directory, and each text file is named "info1.txt", "info2.txt" and so on. How would I open up all of the text files in an array of ifstream objects without having to hard-code all my text file names in? I know the following code does not work, but I think it conveys the idea of what I want to do if it did work:

ifstream myFiles[5];
for(int i = 0; i < 5; i++){
    myFiles[i].open("info" + i + ".txt");
}

I know the solution is probably very simple, but after a lot of research, trial and error I still haven't figured it out. Thanks!

5条回答
The star\"
2楼-- · 2019-02-14 21:16

Your idea should work with a small change:

myFiles[i].open((std::string("info") + itoa(i) + ".txt").c_str());
             // ^^^^^^^^^^^           ^^^^

Also note that, you cannot use std::vector because ifstream is not a copyable object. So continue using the array.

查看更多
欢心
3楼-- · 2019-02-14 21:22

I usually use std::stringstream:

{
  std::stringstream filename;
  filename << "info" << i << ".txt" << std::ends;
  myFiles[i].open(filename.str().c_str());
}
查看更多
爷的心禁止访问
4楼-- · 2019-02-14 21:27

For building the file names, I'd use std::ostringstream and operator<<.

If you want to use a container class like std::vector (e.g. because you don't know at compile time how much big the array of ifstream's will be), since std::ifstream is not copyable, you can't use vector<ifstream>, but you can use vector<shared_ptr<ifstream>> or vector<unique_ptr<ifstream>>; e.g.:

vector<shared_ptr<ifstream>> myFiles;
for (int i = 0; i < count; i++)
{
    ostringstream filename;
    filename << "info" << i << ".txt";
    myFiles.push_back( make_shared<ifstream>( filename.str() ) );        
}

With unique_ptr (and C++11 move semantics):

vector<unique_ptr<ifstream>> myFiles;
for (int i = 0; i < count; i++)
{
    ostringstream filename;
    filename << "info" << i << ".txt";
    unique_ptr<ifstream> file( new ifstream(filename.str()) );
    myFiles.push_back( move(file) );
}

unqiue_ptr is more efficient than shared_ptr, since unique_ptr is just a movable pointer, it's not reference counted (so there is less overhead than shared_ptr). So, in C++11, you may want to prefer unique_ptr if the ifstream's are not shared outside the vector container.

查看更多
beautiful°
5楼-- · 2019-02-14 21:38

You can have an array of ifstream objects, but if you need a dynamic length, then you cannot do it this way, nor will std::vector<ifstream> work.

So you will need pointers. std::vector<ifstream*> will work but you might use shared_ptr so std::vector<shared_ptr<ifstream> > will work. If you have unique_ptr available you can use that instead of shared_ptr.

Each element will then have to be created with new.

You will also need to create the string properly, you can use a boost::format or ostringstream or even an old-fashioned sprintf to do that.

By the way, I would search boost's filesystem library to see if they have a more dynamic ifstream that can go happily in your vector without the messiness of shared_ptr.

查看更多
Animai°情兽
6楼-- · 2019-02-14 21:40

The problem is, I guess, the part about dynamically creating the file name.

One of the simple solutions is to use std::ostringstream to do it:

ifstream myFiles[5];
for(int i = 0; i < 5; i++){
    ostringstream filename;
    filename << "info" << i ".txt";
    myFiles[i].open(filename.str());
}

If your library is to old for it to accept std::string arguments in the call to open then use

    myFiles[i].open(filename.str().c_str());
查看更多
登录 后发表回答