Re: ifstream::get() surprise

From: Jacek Dziedzic (jacek__NOSPAM___at_janowo.net)
Date: 08/27/04


Date: Fri, 27 Aug 2004 06:05:47 +0200

Mike Wahler wrote:

>>
>>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.

   Obviously, but not in the famous "shortest possible program
displaying the behaviour", right?

> Also note that 'get()' is an unformatted input function.
> Using it with a text-mode stream (the default) could have
> unexpected results.

   What unexpected results, could you clarify?

> If you want to read unformatted,
> open with 'std::ios::binary'.

   Nope, I want to read formatted. Binary mode is out because
I don't want to mind CR/LF differences. Plus I'm reading
trivial configuration text files.

> But I think you're probably
> just using the wrong function. See below.
>

   So what's wrong with get()?

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

   Yes, but I don't have these.

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

   I see that now, but it's not obvious a'priori. Some read functions
don't complain about reading zero bytes or seek functions don't
complain about seeking zero bytes. I mean it's obvious for someone
who KNOWS already, but for me it was counter-intuitive.

> ============== 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 ===========================
>

   Yes, that was helpful.

> 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];

   You overdid that one a bit, Mike :). I am in the middle of
coding a 'better_ifstream' class which inherits from ifstream
and supplies facilities like get_string(), get_word(),
parse_phrase(), etc.
std::strings are useless in my problem, since I need
byte-copiable POD types to be transferred across different
processors in a parallel system. But you couldn't have known that,
since the rule is to post the shortest code suffering from the
questioned behaviour, not the *neatest* shortest code, right? :)

> HTH,
> -Mike

   yes, the quote did,
- J.



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)
  • Re: test if handle exists? How???
    ... > ishandlegives an array of nine 0s ... does not work because 'handles.c' is a literal character vector of 9 characters and that character vector is not an empty array. ... If what you are trying to do is find out whether there is a graphics object with the tag 'abcdef' then use ...
    (comp.soft-sys.matlab)
  • Re: easy parsing problem in C for beginner
    ... As far as I can tell you're getting an array of time slot priorities ... so I went with the WHILE loops and my own counter. ... char prio = PA_GetArrayElementAtIndex; ... characters are in that array. ...
    (comp.sys.mac.programmer.help)
  • Re: test if handle exists? How???
    ... The problem is with the script but even replicating it on the command line ... ishandlegives an array of nine 0s ... does not work because 'handles.c' is a literal character vector of 9 characters and that character vector is not an empty array. ... If what you are trying to do is find out whether there is a graphics object with the tag 'abcdef' then use ...
    (comp.soft-sys.matlab)
  • 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)