ifstream errors

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • adramolek@gmail.com

    ifstream errors

    So... I'm trying to get used to using C++ ifstream (or ofstream)
    instead of stdio (although I'm having second thoughts). Anyways, I
    want to be able to display a meaningful error message if ifstream
    fails to open a file, but nothing I read about ifstream says anything
    about a reliable place to get an error message. Using stdio I can
    simply do:

    FILE *f = fopen(filename, "rb");
    if (!f)
    perror(filename );

    So far the best I've been able to do using ifstream is:

    ifstream f(filename, ios_base::in | ios_base::binar y);
    if (!f.is_open())
    cerr << filename << ": tough luck!" << endl;

    What is a reliable way to get a real error message? Even the example
    at cplusplus.com:



    Gives a crappy error message.

    Thanks,
    AJ
  • adramolek@gmail.com

    #2
    Re: ifstream errors

    On Mar 27, 4:29 am, adramo...@gmail .com wrote:
    What is a reliable way to get a real error message?
    Oh, also, related to this, how do I tell if >fails? Say I am reading
    4 integers from an ifstream opened in text mode. Using stdio:

    int a, b, c, d;
    if (fscanf(infile, "%i%i%i%i", &a, &b, &c, &d) != 4)
    fprintf(stderr, "error parsing line\n");

    But using ifstream:

    int a, b, c, d;
    infile << a << b << c << d;
    // how to check for failure...?


    Thanks

    Comment

    • adramolek@gmail.com

      #3
      Re: ifstream errors

      On Mar 27, 4:33 am, adramo...@gmail .com wrote:
      infile << a << b << c << d;

      That is, >>

      Comment

      • Michael.Boehnisch@gmail.com

        #4
        Re: ifstream errors

        On 27 Mrz., 09:33, adramo...@gmail .com wrote:
        [..]
        But using ifstream:
        >
        int a, b, c, d;
        infile << a << b << c << d;
        // how to check for failure...?
        if ( infile.fail() ) {
        ....
        }

        best,

        Michael

        Comment

        • James Kanze

          #5
          Re: ifstream errors

          On Mar 27, 9:29 am, adramo...@gmail .com wrote:
          So... I'm trying to get used to using C++ ifstream (or
          ofstream) instead of stdio (although I'm having second
          thoughts). Anyways, I want to be able to display a meaningful
          error message if ifstream fails to open a file, but nothing I
          read about ifstream says anything about a reliable place to
          get an error message. Using stdio I can simply do:
          FILE *f = fopen(filename, "rb");
          if (!f)
          perror(filename );
          Whether that gives you something meaningfull or not depends
          somewhat on the implementation. What perror outputs depends on
          errno, and the standard really doesn't specify too much in this
          regard.
          So far the best I've been able to do using ifstream is:
          ifstream f(filename, ios_base::in | ios_base::binar y);
          if (!f.is_open())
          cerr << filename << ": tough luck!" << endl;
          Why not?

          ifstream f(filename, ios_base::in | ios_base::binar y);
          if (!f.is_open())
          perror( filename ) ;

          You're very much in the domain of implementation defined, or
          even unspecified, both with FILE* and ifstream, but in general,
          I'd expect both of them to behave more or less identically here.
          (Under Unix, I'm pretty sure they will; errno is set by the
          functions in the system API which ifstream or fopen must call.
          They seem to behave the same under Windows as well, at least
          with VC++.)

          --
          James Kanze (GABI Software) email:james.kan ze@gmail.com
          Conseils en informatique orientée objet/
          Beratung in objektorientier ter Datenverarbeitu ng
          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

          Comment

          • James Kanze

            #6
            Re: ifstream errors

            On Mar 27, 9:33 am, adramo...@gmail .com wrote:

            [...]
            int a, b, c, d;
            if (fscanf(infile, "%i%i%i%i", &a, &b, &c, &d) != 4)
            fprintf(stderr, "error parsing line\n");
            But using ifstream:
            int a, b, c, d;
            infile << a << b << c << d;
            // how to check for failure...?
            if ( ! infile ) ...

            You can use an istream as a boolean; it will behave as true if
            no error has occured, and as false once an error has been seen.
            Once you've detected an error (and only then), you can use more
            specific functions to determine the cause:

            if ( ! infile ) {
            if ( infile.bad() ) {
            // Serious hardware problem... (read error, etc.)
            // A lot of implementations aren't too rigorous
            // about reporting this, and you might never see
            // it.
            } else if ( ! infile.eof() ) {
            // Format error in the input stream.
            } else {
            // Probably an end of file (although in a few rare
            // cases, infile.eof() can return true even though
            // there was a format error in the input).
            }
            }

            The error condition is sticky: it must be cleared (function
            istream::clear( )) before you can read further (or do anything
            else) with the stream.

            A typical idiom for reading files is:

            while ( infile >a >b >c ) {
            // ...
            }

            or (more often, because it allows better recovery in case of a
            format error):

            std::string line ;
            while ( std::getline( infile, line ) ) {
            std::istringstr eam parse( line ) ;
            parse >a >b >c >d >std::ws ;
            if ( ! parse || parse.peek() != EOF ) {
            // Syntax error in the line...
            } else {
            // ...
            }
            }

            This has the advantage of not putting the main input in an error
            state, and leaving it correctly positionned for further reading
            in case of an error. (Like fscanf, the >operators treat a new
            line as white space. So if the input syntax is line oriented,
            you probably want to use getline to read it, and istringstream
            to parse each line. Something like you'd use fgets to read and
            sscanf to parse in C, except that it doesn't require any special
            handling for excessively long lines.)

            --
            James Kanze (GABI Software) email:james.kan ze@gmail.com
            Conseils en informatique orientée objet/
            Beratung in objektorientier ter Datenverarbeitu ng
            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

            Comment

            • Jim Langston

              #7
              Re: ifstream errors

              adramolek@gmail .com wrote:
              On Mar 27, 4:29 am, adramo...@gmail .com wrote:
              >What is a reliable way to get a real error message?
              >
              Oh, also, related to this, how do I tell if >fails? Say I am reading
              4 integers from an ifstream opened in text mode. Using stdio:
              >
              int a, b, c, d;
              if (fscanf(infile, "%i%i%i%i", &a, &b, &c, &d) != 4)
              fprintf(stderr, "error parsing line\n");
              >
              But using ifstream:
              >
              int a, b, c, d;
              infile << a << b << c << d;
              // how to check for failure...?
              >
              >
              Thanks
              if ( infile >a >b >c >d )
              // success
              else
              // failure

              Alternately

              if ( ! ( infile >a >b >c >d ) )
              // failure
              else
              // success


              --
              Jim Langston
              tazmaster@rocke tmail.com


              Comment

              • Ron Natalie

                #8
                Re: ifstream errors

                adramolek@gmail .com wrote:
                >
                FILE *f = fopen(filename, "rb");
                if (!f)
                perror(filename );
                >
                If your machine has perror, it probably has strerror
                which returns a char* with the same content.

                Comment

                • adramolek@gmail.com

                  #9
                  Re: ifstream errors

                  On Mar 27, 7:57 am, Ron Natalie <r...@spamcop.n etwrote:
                  adramo...@gmail .com wrote:
                  >
                  FILE *f = fopen(filename, "rb");
                  if (!f)
                  perror(filename );
                  >
                  If your machine has perror, it probably has strerror
                  which returns a char* with the same content.
                  Thanks for your reply. Mostly what I was wondering about was if
                  ifstream sets errno.

                  Comment

                  • adramolek@gmail.com

                    #10
                    Re: ifstream errors

                    On Mar 27, 4:53 am, Abhishek Padmanabh <abhishek.padma n...@gmail.com>
                    wrote:
                    Using member operator! to test file open failure might make it look
                    easier.
                    Hey cool, thanks for the tip.
                    Failures with fstream objects are notified by setting the following
                    bits: eofbit, failbit and badbit. So, if you want granularity in
                    reporting errors, you would need to check them individually.
                    I see; this makes sense. It should be enough... mostly I'd like to be
                    able to notify the user about things like "file not found" as opposed
                    to "permission denied", though. Well I guess really those are the two
                    big errors. In the end it's not critical, it's just something I was
                    wondering about.

                    Thanks again, that helps a lot
                    AJ

                    Comment

                    • adramolek@gmail.com

                      #11
                      Re: ifstream errors

                      On Mar 27, 6:24 am, James Kanze <james.ka...@gm ail.comwrote:
                      [a great reply]
                      Thanks a lot! That clears a lot of stuff up. The istringstream is
                      pretty cool, I was wondering if there was something like that.

                      I have one small new question left: Do istreams have anything like
                      scanf's %[] for matching only characters in a set (I think of it like
                      the poor man's regular expression)? It's something I've found pretty
                      handy sometimes in the past.

                      Thanks again,
                      AJ

                      Comment

                      • James Kanze

                        #12
                        Re: ifstream errors

                        On Mar 27, 1:46 pm, adramo...@gmail .com wrote:
                        On Mar 27, 6:24 am, James Kanze <james.ka...@gm ail.comwrote:
                        I have one small new question left: Do istreams have anything
                        like scanf's %[] for matching only characters in a set (I
                        think of it like the poor man's regular expression)? It's
                        something I've found pretty handy sometimes in the past.
                        No, but unlike scanf, it's totally extensible. I don't think
                        I've ever written an application where we didn't have some user
                        defined extractors or manipulators. Often, too, I'll use
                        something more or less like a decorator (it is a decorator,
                        vis-a-vis iostream), to control input or output in some special
                        way. Just write an extractor which operates indirectly on your
                        string.

                        Alternatively, you don't necessarily need a poor man's
                        replacement. Boost regular expressions works very well, and is
                        in the process of being adopted into the standard.

                        --
                        James Kanze (GABI Software) email:james.kan ze@gmail.com
                        Conseils en informatique orientée objet/
                        Beratung in objektorientier ter Datenverarbeitu ng
                        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                        Comment

                        Working...