Hi,

I would need to create unique filenames appended by the iteration number.
For eg.

for( i=0;i<iterations;i++){
  ofstream outfile("iterfile"+"i"); // i.e filename should be iterfile0 for 1st iteration.
}

I need to cast "i" from int to char so I tried

ofstream outfile("iterfile"+(char)i)

but it did not work. How do I do this correctly?

Dani AI

Generated

The expression "iterfile" + i does not do string concatenation — the string literal decays to a pointer and adding an integer moves that pointer (so the result is not a new filename). A simple, modern C++ approach is to convert the integer to a string (for example with std::to_string) and build a std::string which can be given to std::ofstream (the std::string overload is available since C++11; older compilers may need .c_str()). This answers the original type/concat issue and avoids casting the integer to char. (docs.cppreference.com)

A couple of practical patterns (both are more C++-style than sprintf as discussed by and ):

  • Simple concatenation with std::to_string:
std::string name = "iterfile" + std::to_string(i);
std::ofstream outfile(name); // check outfile for open errors
  • If fixed-width numbers are wanted (iterfile001, etc.), use an ostringstream with manipulators:
std::ostringstream ss;
ss << "iterfile" << std::setw(3) << std::setfill('0') << i;
std::string name = ss.str();
ss.str(""); ss.clear(); // or recreate ss each loop

String streams and the <iomanip> manipulators make padding and formatting straightforward; creating a new ostringstream each iteration is cheap and avoids manual clearing. (en.cppreference.com)

If the goal is absolute uniqueness (avoid overwriting files across runs or processes), check for existing names with std::filesystem::exists or use platform-safe temp-file APIs. Beware of race conditions when testing-for-existence then creating a file; portable safe unique-file creation is outside simple per-iteration naming and is why some conveniences (like unique_path) were not elevated into the standard without care. Use std::filesystem::path to build paths portably. (cppreference.com)

Summary: sprintf works (as used by ), but prefer std::to_string/std::ostringstream for clearer, safer C++ code and use std::filesystem helpers when file-existence or portability matters.

Recommended Answers

All 6 Replies

You can use a stringstream(). Remember to call mystringstream.str(""); at the beginning of your loop to clear it out (otherwise all the filenames will get stuck together as you go). Also, remember that ofstream takes a const char* for the filename so you need to use the .c_str() method of your resulting string (so your resultant string would be accessed as mystringstrim.str().c_str() .

You can use sprintf()

<stdio.h>
sprintf(fileName,"iterfile%d",i);

stringstreams are a much cleaner solution than dirty C sprintf functions and should definitely be preferred when writing C++ code

stringstreams are a much cleaner solution than dirty C sprintf functions

Really? The only "dirty" thing I can think of (tedious would be my choice of words) is no std::string support in sprintf. So you need to figure out the maximum size of the file name buffer beforehand. Aside from that, sprintf doesn't seem any dirtier than stringstream for this particular use.

Yes, I find the use of C functions like sprintf dirty in C++ code. I guess I should've mentioned that this is somewhat a personal preference and not a strict rule though ;).

So I guess now the OP has all the information to chose between tedious(yes, it is a better description) or (in my eyes) cleaner solution ^^.

Dear all.

I used the sprintf version for the moment. I played around with stringstreams but was not successful. I shall do this once I get the major coding done :)
Thank you very much.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.