clang 3.3/Xcode & libc++: std::getline does not read data after calling ifstream::clear()

≯℡__Kan透↙ 提交于 2019-12-22 07:06:40

问题


The following program demonstrates an inconsistency in std::getline behavior between libc++ and libstdc++ (using clang3.3).

The program opens the file testfile, reads it until eof, then clears the error bits using ifstream::clear and tries to read from the same filehandle again to see if new data was appended to the file.

#include <fstream>
#include <iostream>
#include <unistd.h>

using namespace std;

int main() {
    ifstream* file = new ifstream("testfile");
    if ( ! file->is_open() ) {
        cout << "testfile does not exist" << endl;
        return -1;
    }

    while ( 1 ) {
        file->clear(); // remove end of file evil bits
        string line;

        // workaround:
        // file->seekg(file->tellg());

        while ( getline(*file, line) )
            cout << "read line: " << line << endl;

        if ( file->eof() )
            cout << "File reports eof after getline\n";

        usleep(1000000);
    }
}

Using libstdc++ (no matter which compiler), if you append data to testfile while the program is running, the data will be read by the getline call in the next loop iteration.

In clang 3.3 on OS-X with libc++, after the first time the file end is encountered, getline will always fail and set the eof bit on all following calls, without reading any data that has been appended to the file. Uncommenting the workaround, which just seeks to the current position restores libstdc++ behavior. Compiling against libstdc++ with clang++ -stdlib=libstdc++ also reverts to the old behavior.

Does anyone know if this is an expected change? Am I trying to do this in a way that is not supported or is this some problem of current libc++ versions?

The clang version that triggers this behavior for me is the most recent one shipped with XCode for Mavericks:

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

The libc++ library that is linked against has this version information:

/usr/lib/libc++.1.dylib:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libc++abi.dylib (compatibility version 1.0.0, current version 48.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

回答1:


To synchronize the internal buffer of the ifstream with the external device you need to call:

file->sync();


来源:https://stackoverflow.com/questions/19558376/clang-3-3-xcode-libc-stdgetline-does-not-read-data-after-calling-ifstream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!