clang 3.3 / Xcode& libc ++:std :: getline在调用ifstream :: clear()后不读取数据

时间:2013-10-24 06:18:53

标签: c++ clang ifstream libstdc++ libc++

以下程序演示了libc ++和libstdc ++之间std :: getline行为的不一致性(使用clang3.3)。

程序打开文件testfile,读取它直到eof,然后使用ifstream :: clear清除错误位并再次尝试从同一个文件句柄读取以查看是否有新数据附加到文件中。

#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);
    }
}

使用libstdc ++(无论哪个编译器),如果在程序运行时将数据附加到testfile,则在下一次循环迭代中getline调用将读取数据。

在带有libc ++的OS-X上的clang 3.3中,在第一次遇到文件结束后,getline将始终失败并在所有后续调用中设置eof位,而不读取任何附加到文件的数据。取消注释解决方法,它只是寻求当前位置恢复libstdc ++行为。使用clang ++ -stdlib = libstdc ++对libstdc ++进行编译也会恢复旧的行为。

有谁知道这是否是预期的变化?我是否试图以不支持的方式执行此操作,或者这是当前libc ++版本的一些问题?

对我来说触发此行为的clang版本是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

链接的libc ++库具有以下版本信息:

/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 个答案:

答案 0 :(得分:2)

要将ifstream的内部缓冲区与您需要调用的外部设备同步:

file->sync();