2012/4/27 Jim Michaels <jmichae3@yahoo.com>
by the way, this was a bug report, but a support request.  but really this "bug report" has just morphed into an ECO for a serious reason.

please note that I am not doing getline.  totally different operation.  I will show you why.

I would like to submit an Engineering Change Order against iostream and ifstream.  .good() includes .eof() and is better. I tried modifying the code for .eof and it still doesn't work.  checking for .eof() after cin'ing a number doesn't work.
the problem seems to be the whitespace (
space, cr, lf) AFTER the 1 in the text file which is in SO MANY windows systems when people simply do
echo 1 > somefile.txt
in windows systems.

no amount of checking for .eof() or .good() will remedy that, because EOF hasn't come yet!  there's still whitespace to chew up.  By behavior I believe istream::operator>>()  eats whitespace and THEN gets the value.  this is the way it's acting.  but it sure doesn't act nice when it's the last value!  you always get  the same one twice unless you make your own input system. 

because nothing short of a function that chews up that trailing whitespace is going to fix that and get you to that EOF so you can detect .eof() or .good() which includes .eof().
in fact, such a method OUGHT to be part of istream and ifstream and part of everybody's input reading method before checking for .eof() or .good() 

for example, usage of the method I am proposing might look something like this

//this assumes the existence of std::istream.eatws() and std::ifstream.eatws()


#include <fstream>
#include <iostream>
int main(int argc, char * argv[], char * envp[]) {
    int n;
    std::ifstream filein;
    filein.open("somefile.txt", std::ifstream::in);
    if (!filein.good() && !filein.eof()) {

        filein.close();
        std::cerr << "ERROR: unable to open file \"somefile.txt\"" << std::endl;
        return 1;
    }
    do {
        filein >> n;
        filein.eatws();

        std::cout << n << std::endl;
    } while (!filein.eof());
    filein.close();
    return 0;
}



manually eating whitespace after inputting a value allows you to get the file pointer right to the next value OR another value directly.

...instead of getting a pointer to the next whitespace before EOF.


so I am proposing an official change in iostream and ifstream.

I have not some up with my own code for such a method.  but I might be able to.

this problem is not specific to gcc. it is in borland c++ 5.5.1 as well.

It's not specific to any compiler/environment, it's specific to Standard C++.

The idiomatic way to read input using C++ I/O streams (basic_istream<T>), is by using the (C++03) implicit (C++11) explicit conversion to bool of the stream object:

int main()
{
ifstream stream("somefile.txt");
int i;
while(stream >> i)
{
   //do stuff with i
}

You must check the stream state *after the read*, how else is it going to communicate a failure?

The double last input is because you don't change the integer because extracting from a failed stream does not change the integer.

See for a C++ design explanation for example here: http://stackoverflow.com/questions/1039667/why-does-stdfstream-set-the-eof-bit-the-way-it-does




operator>>() doesn't figure out until it has eaten the whitespace and is about to try to consume a value (it thinks) that it has hit EOF. but for some interesting reason I guess because it doesn't know what best to do when it hits EOF at that point, it simply spits out the last value it had and throws up its hands in disgust, since it can't return EOF or give any indication of failure - it's a 1-trick pony.

...and it doesn't throw.

To make iostreams throw, *you* need to set the stream exceptions flag: http://en.cppreference.com/w/cpp/io/basic_ios/exceptions

Please get a good C++ book, read up on what problems you are experiencing, because all these problems will be caused by the programmer.

Ruben
 




From: Ruben Van Boxem <vanboxem.ruben@gmail.com>
To: mingw-w64-public@lists.sourceforge.net
Sent: Wednesday, April 25, 2012 2:25 PM
Subject: Re: [Mingw-w64-public] ifstream reads once too many times?

Op 25 apr. 2012 23:07 schreef "Jim Michaels" <jmichae3@yahoo.com> het volgende:
>
>
> #include <fstream>
> #include <iostream>
> int main(int argc, char * argv[], char * envp[]) {
>     int n;
>     std::ifstream filein;
>     filein.open("somefile.txt", std::ifstream::in);
>     if (!filein.good()) {
>         filein.close();
>         std::cerr << "ERROR: unable to open file \"somefile.txt\"" << std::endl;
>         return 1;
>     }
>         filein >> n;
>     if (filein.good()) {
>         std::cout << n << std::endl;
>     }
>     while (filein.good()) {
>         std::cout << n << std::endl;
>         filein >> n;
>     }
>     filein.close();
>     return 0;
> }
>
> somefile.txt contains a 1
> but mingw-w64 outputs
> 1
> 1
> this happens with 20111127. it happens with
>
> I have tried rearranging this to 
> #include <fstream>
> #include <iostream>
> int main(int argc, char * argv[], char * envp[]) {
>     int n;
>     std::ifstream filein;
>     filein.open("somefile.txt", std::ifstream::in);
>     if (!filein.good()) {
>         filein.close();
>         std::cerr << "ERROR: unable to open file \"somefile.txt\"" << std::endl;
>         return 1;
>     }
>     if (filein.good()) {
>         filein >> n;
>         std::cout << n << std::endl;
>     }
>     while (filein.good()) {
>         filein >> n;
>         std::cout << n << std::endl;
>     }
>     filein.close();
>     return 0;
> }
>
> but it makes no difference.  same result.  this also happens with mingw also.
http://lmgtfy.com/?q=c%2B%2B+getline+one+line+too+many
This is not the first time I'm telling you this: this is not a general programming question mailing list.
This has to be the most easy thing to Google...
Ruben
>
>
>
> -------------
> Jim Michaels
> jmichae3@yahoo.com
> JimM@JimsComputerRepairandWebDesign.com
> http://JimsComputerRepairandWebDesign.com
> http://JesusnJim.com (my personal site, has software)
> ---
> Computer memory measurements, SSD measurements, microsoft disk size measurements (note: they will say GB or MB or KB or TB when it is not!):
> [KiB] [MiB] [GiB] [TiB]
> [2^10B=1,024B=1KiB]
> [2^20B=1,048,576B=1MiB]
> [2^30B=1,073,741,824B=1GiB]
> [2^40B=1,099,511,627,776B=1TiB]
> hard disk industry disk size measurements:
> [KB] [MB] [GB] [TB]
> [10^3B=1,000B=1KB]
> [10^6B=1,000,000B=1MB]
> [10^9B=1,000,000,000B=1GB]
> [10^12B=1,000,000,000,000B=1TB]
>
>
>
> ------------------------------------------------------------------------------
> Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and
> threat landscape has changed and how IT managers can respond. Discussions
> will include endpoint security, mobile security and the latest in malware
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> Mingw-w64-public mailing list
> Mingw-w64-public@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public



------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public