This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

bug in istream::get(streambuf& sb, char delim)


I've sent this before and didn't receive any feedback. Is my example code
wrong or is istream::get buggy?

istream::get(streambuf& sb, char delim) is called 1 too many times in the
following code:

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <strstream>

int
main()
{
  // bug.dat can be any text file
  ifstream input("bug.dat", ios::in);
  if (!input) {
    cerr << "unable to open 'bug.dat'" << endl;
    return(1);
  }

  size_t line_num = 0;

  for (;;) {
    strstreambuf line;
    input.get(line, '\n');	// problem here - eofbit not set correctly
    if (input.eof()) {
      break;
    }
    else if (input.fail()) {
      cerr << "failure on line " << line_num << endl;
      return 1;
    }

    input.ignore(1, '\n');	// skip newline
    ++line_num;
  }

  cerr << "read " << line_num << " lines" << endl;
  return 0;
}

The problem is really noticable if you run this code that reads from stdin
and you enter text interactively (you have to enter ^D twice to get it to
terminate):

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <strstream>

int
main()
{
  size_t line_num = 0;

  for (;;) {
    strstreambuf line;
    cin.get(line, '\n');	// problem here - eofbit not set correctly
    if (cin.eof()) {
      break;
    }
    else if (cin.fail()) {
      cerr << "failure on line " << line_num << endl;
      return 1;
    }

    cin.ignore(1, '\n');	// skip newline
    ++line_num;
  }

  cerr << "read " << line_num << " lines" << endl;
  return 0;
}

I don't know enough about the libio internals to know if this patch is 
correct, but it makes the above programs give the expected results.

--- libio/isgetsb.cc.buggy	Mon Apr 13 12:36:56 1998
+++ libio/isgetsb.cc	Wed Aug 26 07:43:09 1998
@@ -37,7 +37,13 @@
 	  streamsize len = isb->_IO_read_end - isb->_IO_read_ptr;
 	  if (len <= 0)
 	    if (__underflow(isb) == EOF)
-	      break;
+	      {
+		if (_gcount == 0)
+		  {
+		    set(ios::failbit | ios::eofbit);
+		  }
+		break;
+	      }
 	    else
 	      len = isb->_IO_read_end - isb->_IO_read_ptr;
 	  char *delimp = (char*)memchr((void*)isb->_IO_read_ptr, delim, len);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]