[gnu.g++.lib.bug] Bug in istream::get

David.Detlefs@F.GP.CS.CMU.EDU (08/06/89)

I am using G++ 1.35 and libg++ 1.35.1.

Consider the following program:
--------------------------------------------------
#include <stream.h>

void main() {
  filebuf fin;
  fin.open("bug4-input", input);
  istream ist(&fin);
  char s[100];
  for (int i = 0; i < 50; i++) s[i] = '#';
  ist.get(s, 3);
  cout << "S is " << s << ".\n";
}
--------------------------------------------------

where 'bug4-input' is the file:

--------------------------------------------------
123456789
--------------------------------------------------

When compiled with G++ and libg++, this program prints

S is 1234.

Note that AT&T cfront (1.2.1 and a beta test of 2.0) do *not* print
what you might expect, which is

S is 123.

Instead, they print

S is 12.

An argument can be made that this is correct behavior, since
Stroustrup p. 237 says "... istream::get reads at most n characters
into a character vector starting at p [equivalent to s in this
program]."  Since get inserts the terminating null character in
addition to the characters read, "12\0" are the correct three
characters that should be put in s.

I am in the process of compiling and testing a fix, which I will post
if it works.

Dave

dl@G.OSWEGO.EDU (Doug Lea) (08/06/89)

Oops. Your interpretation of Stroustrup looks correct. Here are the fixes.
(The same counting errors occurred in a couple of places)

g.oswego.edu% cd libg++/src
g.oswego.edu% diff -rc2N stream.cc~ stream.cc
*** stream.cc~	Sun Jul 16 09:26:11 1989
--- stream.cc	Sun Aug  6 07:15:24 1989
***************
*** 321,325 ****
    char ch = 0;
    
!   if (n > 0 && get(ch))
    {
      if (ch == terminator) 
--- 321,325 ----
    char ch = 0;
    
!   if (--n > 0 && get(ch))
    {
      if (ch == terminator) 
***************
*** 328,332 ****
      {
        *s++ = ch; --n;
!       while (n-- >= 0 && get(ch))
        {
          if (ch == terminator)
--- 328,332 ----
      {
        *s++ = ch; --n;
!       while (n-- > 0 && get(ch))
        {
          if (ch == terminator)
***************
*** 387,391 ****
  
    char ch;
!   while (--n >= 0 && get(ch) && ((*s++ = ch) != terminator));
  
    *s = 0;
--- 387,391 ----
  
    char ch;
!   while (--n > 0 && get(ch) && ((*s++ = ch) != terminator));
  
    *s = 0;
g.oswego.edu% diff -rc2N File.cc~ File.cc
*** File.cc~	Thu Jul 20 09:57:26 1989
--- File.cc	Sun Aug  6 07:15:23 1989
***************
*** 379,383 ****
  
    char ch;
!   stat = n;
  
    if (n > 0 && (get(ch)))
--- 379,383 ----
  
    char ch;
!   stat = --n;
  
    if (n > 0 && (get(ch)))
***************
*** 418,422 ****
  
    char ch;
!   stat = n;
  
    while (n > 0 && (get(ch)))
--- 418,422 ----
  
    char ch;
!   stat = --n;
  
    while (n > 0 && (get(ch)))
g.oswego.edu%