Angelika Langer - Training & Consulting
HOME | COURSES | TALKS | ARTICLES | GENERICS | LAMBDAS | IOSTREAMS | ABOUT | NEWSLETTER | CONTACT | Twitter | Lanyrd | Linkedin
 
HOME 
GENERICS 
LAMBDAS 

IOSTREAMS

    BOOK PAGE
    ERRATA
    ABSTRACT
    CONTENT
    PREFACE
    EXCERPT
    QUOTES
    AUTHORS
    REVIEWS
    CODE
    FORUM
    SEMINAR   
 

ABOUT 
NEWSLETTER 
CONTACT 
Errata (2nd Printing)

 
           

Standard C++ IOStreams and Locales

Advanced Programmer's Guide and Reference

Angelika Langer & Klaus Kreft
Addison-Wesley, January 2000
ISBN 0-201-18395-1

Errata (2nd Printing)
 
Thanks to everybody who took the time to send us an email to draw our attention to mistakes and typos in the book. We thank our readers for reading the book so carefully and attentively that you could spot the flaws. Thanks a lot!

Below is a list of errors that have have been identified and have not yet been corrected in the second printing. For a list of errors in the first printing click here

Feel free to send us EMAIL as soon as you detect another mistake.
 
page 71
page 118
page 148 & 161
page 149
page 157 & 159
page 162
page 163&164
page 169
page 171
page 173
page 174
page 215
page 220
page 233
page 240
page 241
page 280
page 303
page 330
page 470
page 490-491
page 491
page 503-505
page 505
page 509
page 510
page 514
page 564
page 566
page 572

page 71:
The last paragraph on this page contains two typos. 

RETRIEVAL AND REPLACEMENT. The concrete stream classes also add another version of the retrieval function rdbuf() , which hides the rdbuf() function inherited from class basic_ios<> . The two functions differ in their return type. The inherited version returns a pointer to the stream base class basic_streambuf< class charT, class Traits> . The added version returns a pointer to a concrete stream buffer type, such as basic_filebuf< class charT, class Traits> . This is the pointer to the contained concrete stream buffer object. The subsequent section explains the subtle differences in more detail.

error found by: 
Chandra Shekhar Kumar, Member Of Technical Staff, Vistaar Systems Pvt. Ltd., January 2002

page 118:
The code sample contains a number of typos. Class istringstream does not have tellp and seekp member functions.  They are called tellg and seekg.

 istringstream buf;
 // fill string stream 
 // read input until a position of interest and memorize the position
 istringstream::pos_type p = buf. tellg ();
 if (p != istringstream::pos_type(-1))
 {  // tellg () was successful
    // read further input
    ...
 }
 // return to the point of interest
 buf. seekg (p);
 // return to beginning of stream
 buf.seekg(0,ios_base::beg);

error found by: 
Klaus Wittlich, Cologne Germany, December 2001

page 148 & 161:
The constructor of class date is incorrect. The fields tm_wday and tm_yday of struct tm are initialized to 0 , which is incorrect for arbitrary dates. The correct values for these fields can be computed by means of the C library function mktime . Change constructor to:

On page 148:

    date(int d, int m, int y)
    {
        tm_date.tm_mday = d; tm_date.tm_mon = m-1; tm_date.tm_year = y-1900;
        tm_date.tm_sec = tm_date.tm_min = tm_date.tm_hour = 0;
        tm_date.tm_wday = tm_date.tm_yday = 0;
        tm_date.tm_isdst = 0;
        mktime(&tm_date);
    }

On page 161:

    date(int d, int m, int y)
    {
        tm_date.tm_mday = d; tm_date.tm_mon = m-1; tm_date.tm_year = y-1900;
        tm_date.tm_sec = tm_date.tm_min = tm_date.tm_hour = 0;
        tm_date.tm_wday = tm_date.tm_yday = 0;
        tm_date.tm_isdst = 0;
        ok = ( (mktime(&tm_date)!=time_t(-1)) && valid() ) ? true : false;
    }

error found by: 
Klaus Wittlich, Cologne Germany, February 2002

page 149:
The code sample contains a typo. Change to:

template<class charT, class Traits>
friend basic_istream<charT,Traits>&
operator>> (basic_istream<charT,Traits>& is, date& dat);

template<class charT, class Traits>
friend basic_ostream<charT,Traits>&
operator<< (basic_ostream<charT,Traits>& os, const date& dat);

error found by: 
Don McCliman, December 2002

page 157&159:
The initialization of iostate variables is incorrect. ios_base::iostate is an implementation-definded type and there need not be an initial value 0 defined.  One should use ios_base::goodbit as an initial value instead. Change to:

page 157: The extractor:
template<class charT, class Traits>
basic_istream<charT, Traits>&
operator>> (basic_istream<charT, Traits >& is, date& dat)
{
  if (!is.good()) return is;
  ios_base::iostate err = ios_base::goodbit ;
  use_facet<time_get<charT,istreambuf_iterator<charT,Traits> > >(is.getloc())
  .get_date(is, istreambuf_iterator<charT,Traits>(),is, err, &dat.tm_date);
  return is;
}

page 159: The extractor:
template<class charT, class Traits>
basic_istream<charT, Traits>&
operator>> (basic_istream<charT, Traits >& is, date& dat)
{
  if (!is.good()) return is;
  ios_base::iostate err = ios_base::goodbit ;
  typename basic_istream<charT,Traits>::sentry ipfx(is);
  if(ipfx)
  {
    use_facet<time_get<charT,istreambuf_iterator<charT,Traits> > >(is.getloc())
    .get_date(is, istreambuf_iterator<charT,Traits>(),is, err, &dat.tm_date);
  }
  return is;
}

error found by: 
Helmut Zeisel, March 2002

page 162:
The code sample contains a typo. Change to:

template<class charT, class Traits>
friend basic_istream<charT,Traits>&
operator>> (basic_istream<charT,Traits>& is, date& dat);

template<class charT, class Traits>
friend basic_ostream<charT,Traits>&
operator<< (basic_ostream<charT,Traits>& os, const date& dat);

error found by: 
Klaus Wittlich, Cologne Germany, December 2001

page 163&164:
The initialization of iostate variables is incorrect. ios_base::iostate is an implementation-definded type and there need not be an initial value 0 defined.  One should use ios_base::goodbit as an initial value instead. Change to:

page 163: The extractor:
template<class charT, class Traits>
basic_istream<charT, Traits>&
operator>> (basic_istream<charT, Traits >& is, date& dat)
{
  if (!is.good()) return is;
  ios_base::iostate err = ios_base::goodbit ;
  ...

page 164: The inserter:
template<class charT, class Traits>
basic_ostream<charT, Traits>&
operator<< (basic_ostream<charT, Traits >& os, const date& dat)
{
  if (!os.good()) return os;
  ios_base::iostate err = ios_base::goodbit ;
  ...

error found by: 
Helmut Zeisel, March 2002

page 169:
The code sample contains a typo. Change to:

cout << "A date like Dec 2, 1978" << " is needed: ";
date d;
cin.exceptions(ios_base::badbit | ios_base::failbit);
try { cin >> d; }
catch (ios_base::failure&)
{ cerr << "date extraction failed" << endl; throw; }
cout << "This is the specified date in US notation: " << d << endl;

error found by: 
Klaus Wittlich, Cologne Germany, December 2001

page 171:
The initialization of iostate variables is incorrect. ios_base::iostate is an implementation-definded type and there need not be an initial value 0 defined.  One should use ios_base::goodbit as an initial value instead. Change to:

The extractor:
template <class charT, class Traits, class Argument>
basic_istream<charT, Traits>& g_extractor
(basic_istream<charT, Traits>& is, Argument& arg)
{
  ios_base::iostate err = ios_base::goodbit ;
  ...

The inserter:
template <class charT, class Traits>
basic_ostream<charT, Traits>& g_inserter
(basic_ostream<charT, Traits>& os, const Argument& dat)
{
  ios_base::iostate err = ios_base::goodbit ;
  ...

error found by: 
Helmut Zeisel, March 2002

page 173:
The code sample contains a couple of mistakes. Change to:

template <class charT, class Traits>
ios_base::iostate get_from(basic_istream<charT, Traits>& is)
{
  ios_base::iostate err = ios_base::goodbit ;
  use_facet< time_get<charT> >(is.getloc()).get_date
   (is, istreambuf_iterator< charT , char_traits< charT > >() ,is, err, &tm_date);
  if (!(*this) || err)
      return ios_base::failbit;
  else
      return ios_base::goodbit;
}

template <class charT, class Traits>
ios_base::iostate print_on(basic_ostream<charT, Traits>& os) const
{
  char const * const patt = "%x";
  char fmt[3];
  basic_stringbuf<charT,Traits> sb;
  ios_base::iostate err = ios_base::goodbit ;
  ...

errors found by: 
Klaus Wittlich, Cologne Germany, December 2001 and Helmut Zeisel, March 2002

page 174:
Part of the sample code for the inserter is incorrect because the fill_n algorithm does not return the advanced output itertor as we had assumed, but returns void instead. The corresponding code must be corrected to: 

else
{
   if (os.flags() & ios_base::left)
   {
      sink = copy(s.begin(), s.end(), sink);
    fill_n(sink,charToPad,os.fill());
   }
   else
   {
    fill_n(sink,charToPad,os.fill());
      sink = copy(s.begin(), s.end(), sink);
   }
}

error found by: 
Steffen Lottermoser, January 2003

page 215:
Incorrect reference in footnote 15. Change to:

15. We use function try blocks for catching exception in these constructors.  If you are not familiar with function try blocks, see section G.9 , Function try Blocks, for further explanation.

error found by: 
Helmut Zeisel, March 2002

page 220:
Incorrect references to appendix. Change to:

This kind of cast is called a downcast and is performed via the dynamic_cast operator. Section G.8 , Dynamic Cast, in appendix G explains the dynamic cast and related issues.

Such a cast is called a peer class cast (see section G.8 , Dynamic Cast, in appendix G for further explanations) and can be safely performed via the dynamic_cast operator.

error found by: 
Helmut Zeisel, March 2002

page 233:
Typo in code sample on bottom of page. Change to:

      template <class charT, class traits>
      unbuffered_streambuf<charT,traits>::int_type
      unbuffered_streambuf<charT,traits>:: pbackfail(int_type c)
      { 
         if (!takeFromBuf)
         {
            if (!traits_type::eq_int_type(c, traits_type::eof()))
               charBuf = traits_type::to_char_type(c);

            takeFromBuf = true;

            return traits_type::to_int_type(charBuf);
         }
         else
            return traits_type::eof();
      }

error found by: 
Angelika Langer, December 2002 and Trebor A. Rude, February 2003

page 240:
An error has been introduced in the second printing. Change the signature of function underflow() to:

template <class charT, class traits>
typename traits::int_type inbuf<charT,traits>::underflow()

error found by: 
Angelika Langer, May 2003

page 241:
The call to the min() algorithm in function buffer_in() requires a type conversion for the first argument. gptr()-eback() is of type int and pbSize is of type  streamsize , but the min() algorithm asks for arguments of the same type. One option would be casting the int argument to type streamsize .  Another option is explicit template argument specification for the min() template.  We prefer the latter. Change the code to:

// determine number of putback characters
streamsize numPutbacks = min <streamsize> (gptr() - eback(), pbSize);

error found by: 
Michael Harbeck, Siemens AG, Germany, May 2003

page 280:
Add a footnote to the example on page 280:

ctype<char> ’s character classification member functions are based on a table, in which the character encoding is the key and a bitmask value of type ctype_base::mask is the value. The bitmask values indicate all classification criteria to which the character conforms. For example, a lowercase letter such as k is associated with the bit mask value

  ctype_base::alpha | ctype_base::lower | ctype_base::print 1

1 There is an ambiguity in the C++ standard regarding the meaning of the character classification flags used by the ctype facet. The standard does not specify how or if the various character properties relate to each other in any way. The result of this ambiguity in the standard is that different implementations of the standard library do different things. Some implementations (e.g. SGI)  require that you specify all character properties like in the example above: a lower case character would be classified as ctype_base::alpha | ctype_base::lower | ctype_base::print. Other implementations (e.g. Microsoft) allow that you only specify some of the properties and leave out others because they are implied: for a lower case character you would only have to specify ctype_base::alpha | ctype_base::lower ; the property ctype_base::print can be omitted because all alphabetic characters are implicitly printable. 

brought to our attention by: 
Matt Austern, April 2002 at the ACCU conference in Warwick, UK

page 303:
Typo in table 6-4. Change to:
 
ctype ctype_byname <char> ctype_byname <wchar_t>
codecvt_byname<char,char, mbstate_t> codecvt_byname <wchar_t,char,
mbstate_t>

error found by: 
Helmut Zeisel, March 2002

page 330:
Missing arguments in call to narrow in code sample. Change to:

template <class CharT>
class umlaut : public ctype_byname<CharT>
{
protected:
  virtual bool do_is_umlaut(CharT c) const
  { switch( narrow(c,'?') )
    { case 'ä': case 'ö': case 'ü':
      case 'Ä': case 'Ö': case 'Ü': return true;
      default: return false;
    }
  }
public:
  explicit umlaut(size_t refs = 0) : ctype_byname<CharT>("German",refs) {}
  bool is_umlaut(CharT c) const { return do_is_umlaut(c); }
};

error found by: 
Helmut Zeisel, March 2002

page 470:
The return type of showmanyc()is incorrect, due to a defect in the standard. Change to:

virtual streamsize showmanyc();

Overrides the base class functionality if it is able to determine more available characters.

error found by: 
Christopher Currie, December 2002

page 490-491:
The same typo in the description of all global functions: the functions return the reference to the stream, that is, i s instead of *this

Change the last two sentences in the description of the first 3 functions in the section GLOBAL FUNCTIONS to:

The return value is is . Failures are indicated by the stream state of is .

Change the last three sentences in the description of the remaining 3 functions in the section GLOBAL FUNCTIONS to:

When no characters are transferred, failure will be indicated by the state of is , and *s will contain only the end-of-string character. The operation calls is.width(0) in any case. Returns is .

error found by: 
Achim Kupferoth, Germany, December 2002

page 491:
Typos in the description ofthe input stream manipulator ws . The manipulator is available not only for tiny character streams, but for any type of stream. Change to:

INPUT STREAM MANIPULATORS

template < class charT, class traits>
  basic_istream< charT , traits >& ws
    (basic_istream< charT , traits >& is);
Manipulator that extracts whitespace characters from the input stream is . Extraction stops when the next character in the input stream is is not a whitespace character or no more characters are available. If the extraction stops because no more characters are available, ios_base::eofbit is set for is .

error found by: 
Achim Kupferoth, Germany, December 2002

page 503-505:
The same typo in the description of all global functions: the functions return the reference to the stream, that is, os instead of *os .  Change the last two sentences in the description of all functions in the section GLOBAL FUNCTIONS to:

The return value is os . Failures are indicated by the stream state of os .

error found by: 
Achim Kupferoth, Germany, December 2002

page 505:
Typos in the description ofthe output stream manipulators. The manipulators are available not only for tiny character streams, but for any type of stream. Also, the character traits do not have a function eos() that would supply an end-of-string character; the end-of-string character is the default-constructed character of a character type. Change to:

OUTPUT STREAM MANIPULATORS

template < class charT, class traits>
  basic_ostream< charT , traits >& endl
    (basic_ostream< charT , traits >& os);
Manipulator that calls first os.put(os.widen('\n')) and then os.flush() . Returns os .

template < class charT, class traits>
  basic_ostream< charT , traits >& ends
    (basic_ostream< charT , traits >& os);
Manipulator that calls os.put( charT() ) and returns os .

template < class charT, class traits>
  basic_ostream< charT , traits >& flush
    (basic_ostream< charT , traits >& os);
Manipulator that calls os.flush() and returns os .

error found by: 
Achim Kupferoth, Germany, December 2002

page 509:
The return type of showmanyc()is incorrect, due to a defect in the standard. Change to:

// get area :
char_type* eback() const;
char_type* gptr() const;
char_type* egptr() const;
void gbump(int n);
void setg(char_type* gbeg, char_type* gnext, char_type* gend);
virtual streamsize showmanyc();
virtual streamsize xsgetn(char_type* s, streamsize n);
virtual int_type underflow();
virtual int_type uflow();

error found by: 
Christopher Currie, December 2002

page 510:
Under the section called "Get Area" function "inavail" should be "in_avail". 

GET AREA
streamsize in_avail ();
Returns the number of bytes available, i.e. egptr()-gptr() . If the get area does not exist or is empty (i.e. gptr()== 0 || eback()>= gptr() ) this->showmanyc() is called and returns the result of this call.

error found by: 
Robert W. Hand, December 2001

page 514:
The return type of showmanyc()is incorrect, due to a defect in the standard. Change to:

virtual streamsize showmanyc();

Returns an estimation of the number of characters that are at least available from the input sequence or –1. If the operation returns –1, calls to this->underflow() and this->uflow() will fail. Otherwise the returned number of characters can be made available by one or more calls to this->underflow() or this->uflow() . The concrete handling depends on the specific derived class. basic_streambuf<charT, traits>::showmanyc() always returns 0.

error found by: 
Christopher Currie, December 2002

page 514:
The description of uflow() is perhaps a little too short. Change to:

virtual int_type uflow ();

Handles the situation where the get area does not exist or is empty (i.e., gptr()== 0 || gptr() >= egptr() ) and behaves like underflow() , but additionally increases the next pointer of the get area. The concrete handling depends on the specific derived class.
basic_streambuf<charT,traits>::uflow() always returns the failure indication traits_type::eof() , because it calls basic_streambuf<charT,traits>::underflow() , which returns traits::eof()

error found by: 
Michael Harbeck, Siemens AG, Germany, May 2003

page 564:
Typo in paragraph STAGE 1. Change to:

%p , if the extracted value is stored as void*.

error found by: 
Helmut Zeisel, March 2002

page 566:
Typo in paragraph A.2 Parsing of bool Values. We used the logic && operator where the bitwise & operator was meant. Change to:

If (str.flags() & ios_base::boolalpha)==0 , ...
If (str.flags() & ios_base::boolalpha)!=0 , ...

error found by: 
Torsten Rennett, Ingenieurbüro RENNETT, Germany, May 2002

page 572:
Typos in the description of Stage 3, where ios_base::internal is mentioned. Change to:

If (str.flags() & ios_base:: adjustfield ) == ios_base:: internal , and a sign occurs in the character sequence created in stage 2, padding is done after the sign.
If (str.flags() & ios_base:: adjustfield ) == ios_base:: internal , and a sign occurs in the character sequence created in stage 2 began with 0x or 0X , padding is done after these two characters.

error found by: 
Achim Kupferoth, Germany, December 2002

  © Copyright 1995-2008 by Angelika Langer.  All Rights Reserved.    URL: < http://www.AngelikaLanger.com/IOStreams/errata2nd.htm  last update: 18 Jul 2008