3

I have a code like this:

# in class definition
std::ofstream m_myFile;

## some where in code
m_myFile.open(filename);

and then in several places, I am writing to file as follow:

m_myFile << "some data to file"<<std::endl;

This is working well, now I need to add a flag to system that when not set, this file should not be created and written to. I have checked and I can run the application if I do this:

if(createFile)
{
      m_myFile.open(filename);
}

and leave the write to file as it is and I am not getting any runtime error on windows. My question is if I am not opening a file and write to its stream, what is the standard behaviour?

Should I get a run time error or the ofstream just forget about the data and not run time error?

I am using Visual Studio 2013.

mans
  • 17,104
  • 45
  • 172
  • 321
  • Constructor of the `std::ofstream` automatically opens the file. You may want to use `std::fstream`, so that you can have a choice of opening with whenever you want and with read `std::fstream::in` or write `std::fstream::out` mode. – iammilind Feb 13 '15 at 12:32
  • @iammilind The point is that I need an ofstream but only some times and I don't want to go everywhere in my code to check if the file is open. – mans Feb 13 '15 at 12:43
  • @iammilind `std::ofstream` has more than one constructor. The constructors which take a string (overloads 2 and 3 [here](http://en.cppreference.com/w/cpp/io/basic_ofstream/basic_ofstream)) attempt to open the stream. The default constructor (overload 1) does not. That's why `std::ofstream::open` also exists. – Bulletmagnet Mar 05 '15 at 09:59

2 Answers2

5

The standard behavior is that the first write fails. This sets the std::ofstream::badbit and further writes are silently ignored.

This silent failure could be changed to an exception by setting m_myFile.exceptions(std::ofstream::badbit), but it's off by default.

You can make any stream (even std::cout) discard its output by creating a "dev null" streambuf and then switching your stream to that buffer (via .rdbuf)

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • @mans Look at this topic. Both high voted answers have code examples, http://stackoverflow.com/questions/8243743/is-there-a-null-stdostream-implementation-in-c-or-libraries – Brandin Feb 13 '15 at 13:47
  • what do you mean by fail? Does it generate any exception or run_time error? Is it allowed? – mans Feb 13 '15 at 16:33
  • What I mean by fail is exactly what I already said: `badbit` is set. This does not generate an exception **unless** you changed the default setting. – MSalters Feb 14 '15 at 12:53
0

If you don't open the file you have a stream with a default constructed file buffer that is being written to and will get discarded when the ofstream is discarded.

Tasos Vogiatzoglou
  • 2,393
  • 12
  • 16
  • is there anything bad about this? Such as consuming a lot of memory or crashing ? What would happen if buffer became full? – mans Feb 13 '15 at 12:45
  • I'd guess yes, depending on how much you write. You could wrap everything around an object and don't write if a file isn't open. This way you won't have to worry about writing to a stream for nothing – Tasos Vogiatzoglou Feb 13 '15 at 12:46
  • @T.C. What do you mean? I already tested the code and it is not failing. – mans Feb 13 '15 at 12:53
  • What I meant is that you are writing to a buffer what will never written out. You could wrap everything around a let's say Logger class and do a if (!osf.is_open()) { return ; } so you don't pay for something you don't use. The code as is won't fail, it's just can be more efficient. – Tasos Vogiatzoglou Feb 13 '15 at 12:58
  • This answer is not correct. Since the first write fails, further writes will not even be attempted. There is no risk at all of a buffer overrun. – MSalters Feb 14 '15 at 12:55
  • @MSalters If a file is not assigned (default constructor) the underline buffer is initialized without a file. Will the sentry be set to fail on the first write ? – Tasos Vogiatzoglou Feb 14 '15 at 13:09
  • Yes: [If the associated file is not open, `overflow` returns Traits::eof() before doing anything.](http://en.cppreference.com/w/cpp/io/basic_filebuf/overflow) – MSalters Feb 14 '15 at 13:11
  • @MSalters You are write, I missed that case – Tasos Vogiatzoglou Feb 14 '15 at 13:34