Bug 50722 - istrstream extraction not working properly
istrstream extraction not working properly
Status: CLOSED UPSTREAM
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.1
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
David Lawrence
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-08-02 12:04 EDT by Jon Gjerde
Modified: 2007-04-18 12:35 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-10-01 11:36:55 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Jon Gjerde 2001-08-02 12:04:20 EDT
From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98)

Description of problem:
Extraction of a double variable from a istrstream consisting of a single 
char should set fail() and ios::failbit. The string "i" and "s" give 
different results!

How reproducible:
Always

Steps to Reproduce:
1.See program below in additional information
2.
3.
	

Actual Results:  if string = "i", result = 2 0;
if string = "s", result = 2 2;

Additional info:

istrstream a("i");
double b;
a>>b;
cout<<ios::failbit<<" "<<a.fail()<<endl;

(Run, look at the result, then change to a("s")).
Comment 1 Jakub Jelinek 2001-08-08 08:36:42 EDT
It is not that surprising, 'i' is prefix of inf, so in that case it failed
on the EOF condition (eofbit is set), while with "s" it failed already on 's'
character.
Anyway, istream::operator>> should check whether it did not actually scan the
number and set failbit too.
Following patch should do the job:
2001-08-07  Jakub Jelinek  <jakub@redhat.com>

        * iostream.cc (do_scan): New.
        (istream::operator>>(long double &)): Use it.
        (istream::operator>>(double &)): Likewise.
        (istream::operator>>(float &)): Likewise.

        * g++.old-deja/g++.other/failbit1.C: New test.

--- gcc/testsuite/g++.old-deja/g++.other/failbit1.C.jj  Wed Aug  8 14:52:09 2001
+++ gcc/testsuite/g++.old-deja/g++.other/failbit1.C     Wed Aug  8 14:51:12 2001
@@ -0,0 +1,21 @@
+#include <strstream>
+#include <iostream>
+
+extern "C" void abort (void);
+
+using namespace std;
+
+int main(void)
+{
+  istrstream a ("i");
+  istrstream b ("s");
+  double c;
+
+  a >> c;
+  b >> c;
+  if (! a.fail ())
+    abort ();
+  if (! b.fail ())
+    abort ();
+  return 0;
+}
--- libio/iostream.cc.jj        Tue Jul 24 20:40:52 2001
+++ libio/iostream.cc   Wed Aug  8 14:37:14 2001
@@ -361,6 +361,19 @@ READ_INT(unsigned long long)
 READ_INT(bool)
 #endif

+static void do_scan(istream *istr, const char *format, ...)
+{
+  streambuf *_strbuf = istr->_strbuf;
+  va_list ap;
+  va_start(ap, format);
+  int errcode = 0;
+  int count = _IO_vfscanf(_strbuf, format, ap, &errcode);
+  if ((errcode & (_IOS_EOF|_IOS_FAIL)) == _IOS_EOF && count != 1)
+    errcode |= _IOS_FAIL;
+  istr->setstate((ios::iostate)errcode);
+  va_end(ap);
+}
+
 istream& istream::operator>>(long double& x)
 {
     if (ipfx0())
@@ -368,10 +381,10 @@ istream& istream::operator>>(long double
        _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
                                  _strbuf);
 #if _G_HAVE_LONG_DOUBLE_IO
-       scan("%Lg", &x);
+       do_scan(this, "%Lg", &x);
 #else
        double y;
-       scan("%lg", &y);
+       do_scan(this, "%lg", &y);
        x = y;
 #endif
        isfx();
@@ -386,7 +399,7 @@ istream& istream::operator>>(double& x)
       {
        _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
                                  _strbuf);
-       scan("%lg", &x);
+       do_scan(this, "%lg", &x);
        isfx();
        _IO_cleanup_region_end (0);
       }
@@ -399,7 +412,7 @@ istream& istream::operator>>(float& x)
       {
        _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
                                  _strbuf);
-       scan("%g", &x);
+       do_scan(this, "%g", &x);
        isfx();
        _IO_cleanup_region_end (0);
       }
Comment 2 Jakub Jelinek 2001-08-17 12:50:16 EDT
I've added that patch into libstdc++-2.96-96.
Comment 3 Benjamin Kosnik 2004-10-01 11:36:55 EDT
Fixed.

Note You need to log in before you can comment on or make changes to this bug.