Writing to file in a loop

The problem is each loop I want to open a different file. I thought the simplest approach would have been to choose a string based on some if statements and pass it to the filename. However, this doesn't work. Presumably the headers dont support each other.

What is the simplest way to do this instead? Without having to rewrite the entire ofstream section multiple times in each for loop?

For example, perhaps I want to sequentially change the title. Then on the first loop it exports to "data1.txt", then "data2.txt" etc.



Also, as a side question, is it possible to re-open a file you have already written to and add more text without clearing text already in there?


Thanks
However, this doesn't work.
Show what you tried. Following should work:
1
2
3
4
5
6
std::string names[3] = {"file.1", "file.2", "file.3"};
for(const auto& s: names) {
    std::ofstream out(s);
    for(int i = 0; i < 10; ++i)
        out << i << '\n';
}

it possible to re-open a file you have already written to and add more text without clearing text already in there?
Yes. Open it in append (each write will be appended to the end) or in "at end" (will set write position at the end of file, but you can rewind it manually if so desired) mode:
1
2
std::ofstream out(filename, std::ios::out | std::ios::ate); //ore std::ios::app
http://en.cppreference.com/w/cpp/io/ios_base/openmode 
However, this doesn't work

You're going to have to be more specific. What do you mean "it doesn't work"?

Presumably the headers dont support each other.

That statement makes no sense.

For example, perhaps I want to sequentially change the title. Then on the first loop it exports to "data1.txt", then "data2.txt" etc.

If your algorithm for determining the file name is that simple, use a stringstream.
1
2
3
4
  stringstream ss;
  ofstream ofs;
  ss << "data" << i << ".txt";
  ofs.open (ss.str().c_str());


is it possible to re-open a file you have already written to and add more text

Yes. Use the ios::app (append) attribute when you open the file.






> ss.str().c_str() It is undefined behavior. temporary string object you get after calling str()
> will be destroyed after calling c_str() but before ofstream open function is executed.

Not with a conforming implementation. ofs.open (ss.str().c_str()); is fine.

When an implementation introduces a temporary object of a class that has a non-trivial constructor, it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor. Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.

There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when a default constructor is called to initialize an element of an array. ...
The second context is when a reference is bound to a temporary ...
So temporary value returned by str() is guaranteed to be destroyed only after open() is finished? Didn't know that.

I was under impression that temporaries could be destroyed at any moment after all direct operations on it were finished, unless their lifetime is extended through const reference.
Should have been more explicit. An example of what failed:

1
2
3
4
string file1 = "data1.txt"; 
ofstream example(file1);
// Write in
example.close();


Probably an obvious reason why this doesn't work.

Using a stringstream should work for my purposes though.

In which way this failed? Compile time error? Runtime error? File just not written?

I'll take a wild guess and ask if C++11 support is enabled. And also I want to know your IDE.
error: no matching function for call to ‘std::basic_ofstream<char>::basic_ofstream(std::string&)’


Compiled using Ubuntu command line. Didn't realise it didn't already support c++11. Just attached it now it compiles, but doesn't save it to a file.

The whole code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main() {

string file1 = "data.txt"

ofstream example(file1);
if ( example.fail() ){
      cerr << "Error opening file for writing" <<endl;
      exit(1);
}
else{
example << 1 << endl;
}

example.close();

return 0;
}
Last edited on
So it compiles, runs, but file is not created? Did you check if file is properly open in your code? Are you sure what executable working directory is? If not, replace relative path with absolute.
That fixed it, cheers.
Topic archived. No new replies allowed.