Formatted input of hex numbers with leading zeros

scott snyder snyder@fnal.gov
Sun Jul 2 21:40:00 GMT 2000


hi -

I think there's a problem with formatted input of hex numbers
with leading zeros.  Here's an example:

------------------------------------------------------------------
#include <string>
#include <sstream>
#include <iostream>

using namespace std;

int main ()
{
  string line = "0381500 1AC1 4";
  istringstream isstream (line);
  int smtfeaddr, smtaddr, nchip;
  isstream >> hex >> smtfeaddr >> smtaddr >> nchip;
  cout << hex << smtfeaddr << " " << smtaddr << " " << nchip << "\n";
  return 0;
}
------------------------------------------------------------------

When i tried out this program, it printed:

3 81500 1ac1

which wasn't exactly what was expected.

It is, in fact, trying to  read the first number as octal, because it
starts with a leading zero.  I don't think that this is correct --- as
far as i can make out from the standard, the conversion should behave
like scanf with `%x', which in turn should behave like strtol with
a base of `16', which should always use a base of 16, regardless
of the input.

Here's an attempt to fix it, along with a test case.

thanks,
sss


2000-07-02  scott snyder  <snyder@fnal.gov>

	* bits/locale_facets.tcc (_M_extract): Only figure out the base
	from the input if base == 0.
	* testsuite/27_io/istream_extractor_arith.cc: Test reading a
	number with a leading `0' in hex mode.


Index: bits/locale_facets.tcc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/bits/locale_facets.tcc,v
retrieving revision 1.6
diff -u -p -c -p -r1.6 locale_facets.tcc
*** locale_facets.tcc	2000/07/02 02:15:26	1.6
--- locale_facets.tcc	2000/07/03 04:38:02
*************** namespace std
*** 386,392 ****
                    __base = 16;
                    __testzero = false; // "0x" is not a leading zero
                  }
!               else
                  __base = 8;
              }
  
--- 386,392 ----
                    __base = 16;
                    __testzero = false; // "0x" is not a leading zero
                  }
!               else if (__base == 0)
                  __base = 8;
              }
  
Index: testsuite/27_io/istream_extractor_arith.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc,v
retrieving revision 1.3
diff -u -p -c -p -r1.3 istream_extractor_arith.cc
*** istream_extractor_arith.cc	2000/06/20 01:24:46	1.3
--- istream_extractor_arith.cc	2000/07/03 04:38:29
***************
*** 31,44 ****
--- 31,47 ----
  std::string str_01;
  std::string str_02("true false 0 1 110001");
  std::string str_03("-19999999 777777 -234234 233 -234 33 1 66300.25 .315 1.5");
+ std::string str_04("0123");
  
  std::stringbuf isbuf_01(std::ios_base::in);
  std::stringbuf isbuf_02(str_02, std::ios_base::in);
  std::stringbuf isbuf_03(str_03, std::ios_base::in);
+ std::stringbuf isbuf_04(str_04, std::ios_base::in);
   
  std::istream is_01(NULL);
  std::istream is_02(&isbuf_02);
  std::istream is_03(&isbuf_03);
+ std::istream is_04(&isbuf_04);
  std::stringstream ss_01(str_01);
   
  // minimal sanity check
*************** bool test01() {
*** 103,108 ****
--- 106,116 ----
    is_03 >> f1;
    test &= f1 == 1.5;
  
+   is_04 >> std::hex >> i1;
+   printf ("%d %d %d\n", i1, i1 == 0x123, test);
+   test &= i1 == 0x123;
+   printf ("%d %d %d\n", i1, i1 == 0x123, test);
+ 
    // test void pointers
    int i = 55;
    void* po = &i;
*************** bool test01() {
*** 110,115 ****
--- 118,124 ----
  
    ss_01 << po;
    ss_01 >> pi;
+   printf ("%x %x\n", pi, po);
    test &= po == pi;
    
  #ifdef DEBUG_ASSERT


More information about the Libstdc++ mailing list