How can I find out what went wrong opening a file with ofstream?

Hi,

I have the following code and need to know why it isn't creating the file:

1
2
3
4
5
6
7
8
	ofstream out{ outputFileName, ios_base::trunc };

	if (!out)
	{
		ostringstream os;
		os << "Cannot open file '" << outputFileName << "'";
		throw ios_base::failure{ os.str() };
	}


How can I find out the reason for failure?

Thanks
Juan
Are you sure that your code compiled?

You use the line
ofstream out{ outputFileName, ios_base::trunc };
and have curly braces {} rather than the normal function ones ().
lastchance wrote:
You use the line
ofstream out{ outputFileName, ios_base::trunc };and have curly braces {} rather than the normal function ones ().

This is valid syntax, since it's a declaration, not a function invocation. See the description of uniform initialization here.
http://www.stroustrup.com/C++11FAQ.html#init-list
Last edited on
If you are using C++11, you can turn on exceptions, open the file and catch the exception. The ios_base::failure excepion should be derived from std::system_error and have a std::error_code associated with the exception. This should provide the low-level details of the error.

If you are using C+03 on Unix, errno should be set and you can get the reason with strerror(errno).
First, code:

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

int main (int, char **) {
  try {
    std:: cerr << "attempting open.\n";
    auto file = std::ofstream{};
    file.exceptions(std::ios::badbit | std::ios::failbit);
    file.open("/root/i-dont-have-permission-to-access-this");

    std::cerr << "open succeeded.\n";

    file << "blah blah blah";

  } catch(std::exception &e) { /* Handle the failure... */
    std:: cerr << "failure.\n  what(): "
               << e.what() << "\n  errno : "
               << strerror(errno) << "\n";
  }
}


And my output
attempting open.
failure.
  what(): basic_ios::clear
  errno : Permission denied


I always prefer to call the exceptions() member function with at least badbit.
badbit is supposed to signal an I/O error of some sort; failbit other issues.

Note that my implementation (Linux 4.7.6, glibc 2.4.1) doesn't return a useful exception description in what(); mine does set errno correctly.

The implementation isn't required to set errno. Under Windows, maybe GetLastError() will yield results.
Last edited on
I turned on exceptions as per your suggestion PanGalactic, but there is not any meaningfull information to be obtained (there is only one error code for ios_base::failure exceptions)...

So? Am I missing something? I know my code is trying to create a file with a name with invalid characters in it ... but I found that by inspection and thought, not by any error code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	ofstream out;
	out.exceptions(ios::failbit | ios::badbit);

	try
	{
		out.open( "5555-****" /*outputFileName*/, ios_base::trunc );
	}
	catch( ios_base::failure& e)
	{
		auto c = e.code();
	        ostringstream os;
	        os << c.category().name() << " " << c.value() << " " << c.message();

               cerr << os.str() << endl;
        }


My output is:

iostream 1 iostream stream error

Last edited on
I tried GetLastError() and got "Broken Pipe" when opening a file for writing when the file is already open by another application so it is unaccesible. Does this message make sense?

Thanks
Juan

BTW, errno is not set in Windows
So? Am I missing something? I know my code is trying to create a file with a name with invalid characters in it ... but I found that by inspection and thought, not by any error code...


I would do as mbozzi illustrates. There is no restriction on characters in a C++ file name. Such restrictions come from the operating system and the exceptions generated by streams tend to only indicate success or failure, not the causse of the failure (possibly because those reasons are not enumerated by the standard either, but by the operating system.) So going to std::strerror for more details makes sense.

http://en.cppreference.com/w/c/string/byte/strerror

[Edit: And errno is set on Windows, at least if you're using VC++.]
Last edited on
Topic archived. No new replies allowed.