How to create an array of ifstream objects and how can I fill this array with numbered text files?

I have a bunch of text files in a directory, and each text file is called "info1.txt", "info2.txt", etc. How can I open all text files in an array of ifstream objects without having to hardcode all the names of my text files? I know that the following code does not work, but I think that it conveys the idea of ​​what I want to do if it works:

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

I know that the solution is probably very simple, but after many studies, trial and error, I still do not understand. Thanks!

+4
source share
5 answers

The problem, I think, is regarding the dynamic creation of the file name.

One simple solution is to use std::ostringstream :

 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 deprecated to accept std::string arguments in an open call, then use

  myFiles[i].open(filename.str().c_str()); 
+5
source

To create file names, I would use std::ostringstream and operator<< .

If you want to use a container class, for example std::vector (for example, because at compile time you don’t know how big the ifstream array will be), since std::ifstream cannot be copied, t use vector<ifstream> , but you can use vector<shared_ptr<ifstream>> or vector<unique_ptr<ifstream>> ; eg:.

 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's 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 more efficient than shared_ptr , since unique_ptr is just a moving pointer, it does not count (therefore, the overhead is less than shared_ptr ). So in C ++ 11, you may prefer unique_ptr if ifstream not outside the vector container.

+5
source

Your idea should work with a little change:

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

Also note that you cannot use std::vector because ifstream not a ifstream object. So keep using the array.

+3
source

I usually use std :: stringstream:

 { std::stringstream filename; filename << "info" << i << ".txt" << std::ends; myFiles[i].open(filename.str().c_str()); } 
+1
source

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

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

Then each item must be created using new .

You will also need to create the string correctly, you can use boost::format or ostringstream or even the old-fashioned sprintf .

By the way, I would look for a quick file system library to see if they have a more dynamic ifstream that can happily work in your vector without the mess of shared_ptr.

0
source

Source: https://habr.com/ru/post/1440715/


All Articles