19

Seems like this should be simple, but I don't find it in a net search.

I have an ofstream which is open(), and fail() is now true. I'd like to know the reason for the failure to open, like with errno I would do sys_errlist[errno].

Sildoreth
  • 1,883
  • 1
  • 25
  • 38
WilliamKF
  • 41,123
  • 68
  • 193
  • 295

5 Answers5

19

The strerror function from <cstring> might be useful. This isn't necessarily standard or portable, but it works okay for me using GCC on an Ubuntu box:

#include <iostream>
using std::cout;
#include <fstream>
using std::ofstream;
#include <cstring>
using std::strerror;
#include <cerrno>

int main() {

  ofstream fout("read-only.txt");  // file exists and is read-only
  if( !fout ) {
    cout << strerror(errno) << '\n'; // displays "Permission denied"
  }

}
Nate Kohl
  • 35,264
  • 10
  • 43
  • 55
  • 6
    That might well work, and strerror() is a standard C++ function. Unfortunately, the standard does not state that open() sets errno, so you can't absolutely depend on it. –  Jun 06 '09 at 22:06
5

Unfortunately, there is no standard way of finding out exactly why open() failed. Note that sys_errlist is not standard C++ (or Standard C, I believe).

2

This is portable but doesn't appear to give useful info:

#include <iostream>
using std::cout;
using std::endl;
#include <fstream>
using std::ofstream;

int main(int, char**)
{
    ofstream fout;
    try
    {
        fout.exceptions(ofstream::failbit | ofstream::badbit);
        fout.open("read-only.txt");
        fout.exceptions(std::ofstream::goodbit);
        // successful open
    }
    catch(ofstream::failure const &ex)
    {
        // failed open
        cout << ex.what() << endl; // displays "basic_ios::clear"
    }
}
DJMcMayhem
  • 7,285
  • 4
  • 41
  • 61
mheyman
  • 4,211
  • 37
  • 34
0

Use:

  • GetLastError() to get error code.
  • FormatSystemMessage(GetLastError()) to get error message.
lfk
  • 57
  • 7
-4

we need not use std::fstream, we use boost::iostream

#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>

void main()
{
   namespace io = boost::iostreams;

   //step1. open a file, and check error.
   int handle = fileno(stdin); //I'm lazy,so...

   //step2. create stardard conformance streem
   io::stream<io::file_descriptor_source> s( io::file_descriptor_source(handle) );

   //step3. use good facilities as you will
   char buff[32];
   s.getline( buff, 32);

   int i=0;
   s >> i;

   s.read(buff,32);

}
thomas
  • 505
  • 3
  • 12