#274 error: getline changes input file

closed-fixed
gcc (462)
2004-08-25
2003-02-03
No

The method getline( basic_istream&, basic_string, Ch
eol ) change the input file. The test program opens a file
(test.txt) for reading and writing with fstream.
The file test.txt contains two lines:

First line
Second line

The first line will read twice and the resulting output of
the file is the following:
sLine.length() = 10 First line
sLine.length() = 12 FiFirst line
Typing
less test.txt
shows that the file was really changed.

Here is the program for test, compiled with
g++ -Wall test.cpp -o Test.exe

g++ --version
g++.exe (GCC) 3.2 (mingw special 20020817-1)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying
conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.

======start test.cpp ========
#include <iostream>
#include <string>
#include <fstream>

int main( int argc, char ** argv )
{
std::string sLine;
std::fstream oStream( "test.txt", std::ios::in |
std::ios::out );
// Go to begin of file
oStream.seekg( 0 );
// Read a line into string
std::getline( oStream, sLine, '\n' );
std::cout << "sLine.length() = " << sLine.length()
<< " "
<< sLine << std::endl;

// Go again to begin of file
oStream.seekg( 0 );
// Read line again in string
std::getline( oStream, sLine, '\n' );
std::cout << "sLine.length() = " << sLine.length()
<< " " << sLine << std::endl;
oStream.close();
return EXIT_SUCCESS;
}
======end test.cpp =========

If I change the second parameter of the fstream
constructor to only std::ios::in there will no error.

Thomas Weber

Discussion

  • Danny Smith

    Danny Smith - 2003-02-04

    Logged In: YES
    user_id=11494

    I can confirm the behaviour you report. A workaround
    is to open text.txt in binary mode either using ios flags
    or by adding in lib/binmode to objects, eg

    g++ test.cpp /mingw/lib/binmode.o

    Perhaps report to gcc bugs to get a more authoritative
    answer and possibly a cleaner fix.

    Danny

     
  • Danny Smith

    Danny Smith - 2003-02-04

    Logged In: YES
    user_id=11494

    FWIW,
    You testcase has expected behaviour with STLport-4.5-
    0119 on mingw.
    STLPort uses relatively low level code for basic io
    operations while GCC's libstdc++ uses stdio calls (in,
    particular, fseek-- and we all no what a PITA it can be
    with text files).

    Danny
    Danny

     
  • Earnie Boyd

    Earnie Boyd - 2003-02-04

    Logged In: YES
    user_id=15438

    I was wondering about that. So make doubly sure that your
    test.txt contains the \r\n line endings or modify the stream
    to _O_BINARY mode.

    We've recently discovered that text files with UNIX line
    endings return unexpected results with regard to ftell/fseek
    when operating in text mode. See the mingw-users archives
    for the ``Snapshot: bison-1.875.0-2003.01.31-1.exe'' thread
    for code that proves this.

    Earnie.

     
  • Thomas Weber

    Thomas Weber - 2003-02-04

    Logged In: YES
    user_id=672321

    Here is the hexdump of the testing file. It contains of course
    the \r\n sequence at the end of line.

    00000000: 4669 7273 7420 6c69 6e65 0d0a 5365 636f First
    line..Seco
    00000010: 6e64 206c 696e 650d 0a nd line..

    Change the line 8/9 to
    std::fstream oStream( "test.txt", std::ios::in );
    and there is no error the file will unchanged. I compiled the
    same file under Linux (Mandrake 9.0, gcc 3.2) and I have no
    error. The test file was unchanged.

    Thomas

     
  • Danny Smith

    Danny Smith - 2004-08-25
    • status: open --> closed-fixed
     
  • Danny Smith

    Danny Smith - 2004-08-25

    Logged In: YES
    user_id=11494

    This is fixed in libstdc++ with gcc-3.4.1
    Danny

     

Log in to post a comment.