Re: ifstream::get() surprise

From: Mike Wahler (mkwahler_at_mkwahler.net)
Date: 08/26/04


Date: Thu, 26 Aug 2004 16:55:05 GMT


"Jacek Dziedzic" <jacek__NOSPAM__@janowo.net> wrote in message
news:cgl2kt$grf$1@korweta.task.gda.pl...
> Hi!
>
> Consider the following program
>
> #include <fstream>
> #include <iostream>
> using namespace std;
>
> int main() {
> ifstream in("test.txt");

You need to check here whether the file was opened
successfully or not, and not proceed if it wasn't.

Also note that 'get()' is an unformatted input function.
Using it with a text-mode stream (the default) could have
unexpected results. If you want to read unformatted,
open with 'std::ios::binary'. But I think you're probably
just using the wrong function. See below.

> char buf[40];
> in.get(buf,40);
> cerr << "Read: *" << buf << "*, trouble: " << !in << endl;
> }
>
> and a file, test.txt, starting with an empty line, ie. a lone EOL
> character on the first line.
>
> I was quite surprised to find out, that under these circumstances
> the aforementioned program produced
> "Read **, trouble: 1".

It's not surprising when you read the specification of 'std::istream::get()'

>
> Why does 'in' go to a fail state?

By design.

>I thought 'get' reads up to
> the terminator, stores all characters into 'buf' and leaves the
> terminator inside the stream. That would mean 'buf' containing
> just a \0 char (no chars read), the EOL still in the stream, but
> why a failed state? There are more lines in the file, so we're
> not eof(), and my understanding of this situation is a
> "successful read of zero characters" rather than "read error".

No such thing as 'successful read of zero characters.' If characters
were requested and none were extracted, that's a 'failure'.

============== begin quote ===========================
   ISO/IEC 14882:1998(E)

   27.6.1.3 Unformatted input functions

       basic_istream<charT,traits>& get(char_type* s, streamsize n,
                         char_type delim );

 7 Effects: Extracts characters and stores them into successive locations
   of an array whose first element is designated by s. (286) Characters
   are extracted and stored until any of the following occurs:

   -- n ­ 1 characters are stored;

   -- end­of­file occurs on the input sequence (in which case the function
      calls setstate(eofbit));

   -- c == delim for the next available input character c(in which case c
      is not extracted).

 8 If the function stores no characters, it calls setstate(failbit) (which
   may throw ios_base::failure (27.4.4.3)). In any case, it then stores a
   null character into the next successive location of the array.

 9 Returns: *this.

       basic_istream<charT,traits>& get(char_type* s, streamsize n)

10 Effects: Calls get(s,n,widen('\n'))

11 Returns: Value returned by the call.
============== end quote ===========================

>
> How then can I distinguish a successfull reading of an empty
> line from an I/O error during reading a line? Of course I have
> no a priori knowledge if these empty lines exist in my parsed
> file or not.

I recommend you eschew the array and use std::strings and
std::getline to parse your file.

std::string s;
while(std::getline(in, s))
    cout << s << '\n';

if(!in.eof())
    cerr << "Error reading\n";

Now you don't have to worry if your array is big enough,
and you can get at individual characters the same way
as from an array, e.g.

char c = s[0];

HTH,
-Mike



Relevant Pages

  • Re: sending echo to all clients
    ... I did initialize it up properly, ... There is only one array and that is an array of pollfd structures named ... as an array of characters only but then I can't because sendsends bytes ... you receive C-style strings, so there's really no point to doing it. ...
    (comp.unix.programmer)
  • Listys Themed Quiz * British Sitcoms * 29/01
    ... Who are the successful writers behind series such as 'The Likely Lads', ... Currently appearing in the sitcom 'Blessed', ... How were the characters played by Richard Beckinsale and Paula Wilcox ...
    (rec.games.trivia)
  • Re: Subquery Confusion
    ... Then I got this crazy idea that an Array can only contain a maximum ... number of characters, ... Then I decide that maybe I'm completely wrong with my query, ... it out of Excel VBA and spit it into Microsoft SQL Server Management ...
    (microsoft.public.excel.programming)
  • Re: Listys Themed Quiz * British Sitcoms * 29/01
    ... >1) Who are the successful writers behind series such as 'The Likely Lads', ... >6) Currently appearing in the sitcom 'Blessed', ... >17) How were the characters played by Richard Beckinsale and Paula Wilcox ... Did it star Karl Howman? ...
    (rec.games.trivia)
  • Re: ifstream::get() surprise
    ... Extracts characters and stores them into successive locations ... > null character into the next successive location of the array. ... since the rule is to post the shortest code suffering from the ...
    (comp.lang.cpp)