vector of ifstreams

Im trying to create a vector containing ifstreams. The code that declares the vector is:
 
std::vector <std::ifstream> ifs;


When I try to create an ifstream and push_back it to the vector, I get an immense set of indecipherable complaints from the compiler. The code thats problematic is:
1
2
std::ifstream f(adrs[i].c_str(), std::ios::in | std::ios::binary); //This line works
ifs.push_back(f); //This line causes the errors 


Does anyone know what I'm doing wrong?

Fafner

The problem is that you can't copy an ifstream object:

1
2
3
4
5
6
//...
private:
    ios_base(const ios_base&);

    ios_base& operator=(const ios_base&);
//... 

Instead, try holding the addresses of your ifstream objects in a vector<ifstream*> container.
Last edited on
std::vector relies on the ability copy objects, which is explicitly disallowed in streams (private copy constructor and operator=()). To do what you want, try:

1
2
3
std::vector <std::ifstream *> ifs;
std::ifstream f(adrs[i].c_str(), std::ios::in | std::ios::binary);
ifs.push_back(&f);


--Rollie
Awesome, thanks;)
Careful with object lifetimes if you use rollie's solution verbatim. The vector will contain an invalid pointer
if f goes out of scope before the vector.
jsmith: thanks for the advice;) The files will not be closed until the very end of the program, so I dont think they will go out of scope before the vector, but its good to know;)

I'm having some more trouble though. Here's my code: http://pastebin.org/336677

I want to print out the No Files message if no files are passed to main. The thing is that even though nothing is passed, it still prints out the number one when run. It seems that there is always one more item in the ifs vector than there should be. Hope that makes sense.

Much appreciated;)

Fafner
What's pastebin.org? It is blocked by my company firewall. You are probably better off posting your main function or at least a relevant portion of it.
Its just a place where you post code for everyone to see;)

Here's the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::string adrs[argc]; //list of adresses passed to main
       std::vector <std::ifstream *> ifs;      //vector containing all ifstreams pointers
       if (argc > 0) {
                //storing adresses in adrs
                for (int i = 0; i < argc; i++) {
                        std::string a(argv[i]);
                        adrs[i] = a;
                }
        } else {
                std::cout << "\nNo files for compilation.\n\n";
                return -1;      //exit
        }
        //Open all files and store them in ifs
        for (int i = 0; i < argc; i++) {
                std::ifstream f(adrs[i].c_str(), std::ios::in);
                ifs.push_back(&f);
        }
       
        std::cout << ifs.size();
argc is always > 0 because argv[0] is always the command that was called.
Last edited on
fafner wrote:
I'm having some more trouble though.


That's because you didn't understand what jsmith meant I think. Rollie's solution is scope sensitive.

1
2
3
4
5
6
	//Open all files and store them in ifs
	for (int i = 0; i < argc; i++) {
		std::ifstream* f = new std::ifstream(adrs[i].c_str(), std::ios::in); // create in free store
		ifs.push_back(f); 
	}
        // Now your pointers won't become invalid when you leave the scope of the for() loop. 


And don't forget to delete all your pointers when you're done with them ;o)
Last edited on
Thank you all ;)
Topic archived. No new replies allowed.