Bug 50722 - istrstream extraction not working properly
Summary: istrstream extraction not working properly
Status: CLOSED UPSTREAM
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
(Show other bugs)
Version: 7.1
Hardware: i386 Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: David Lawrence
URL:
Whiteboard:
Keywords:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2001-08-02 16:04 UTC by Jon Gjerde
Modified: 2007-04-18 16:35 UTC (History)
0 users

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


Attachments (Terms of Use)

Description Jon Gjerde 2001-08-02 16:04:20 UTC
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 12:36:42 UTC
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 16:50:16 UTC
I've added that patch into libstdc++-2.96-96.

Comment 3 Benjamin Kosnik 2004-10-01 15:36:55 UTC
Fixed.


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