C++ 为什么我的代码不打印对给定文件所做的更新

C++ Why doesn't my code print updates made to the give file

我试图用 C++ 编写代码,它在 linux 中做类似 tail -f 的事情。我发现了这个问题: How to read a growing text file in C++? 并实现相同。我创建了一个 temp.txt 并开始做 echo "temp" >> temp.txt。但是我的程序没有打印对文件所做的更新。我做错了什么?这是我正在使用的代码

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

int main()
{
    std::ifstream ifs("temp.txt");

    if (ifs.is_open())
    {
        std::string line;
        while (true)
        {
            while (std::getline(ifs, line)) std::cout << line << "\n";
            if (!ifs.eof()) break; // Ensure end of read was EOF.
            ifs.clear();
            sleep(3);
        }
    }

    return 0;
}

更新

我在 linux 机器上尝试了相同的代码,它工作正常,但它在 Mac 上不起作用。我正在使用 gcc 来编译代码。

gcc -v 给出

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix

更新 2
我进一步调查并意识到我毕竟没有使用 gcc。我已经单独安装了 gcc,现在工作正常。这是 clang 中的错误吗?

以下在附加到文件时有效。

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

int main()                                   
{                                            
    std::ifstream ifs("temp.txt");           

    if (ifs.is_open())                       
    {                                        
        std::string line;                    
        while (true)                         
        {                                    
            while (ifs.good()) { // while we are good            
                std::getline(ifs, line); // read a line    
                if (ifs.eof()) break; // if this is the end, break       
                std::cout << line << "\n";   
            }                                
            ifs.clear(); // clear the error flags                     
            sleep(1); // sleep a bit                        
        }                                    
    }                                        

    return 0;                                
}                                            

对于一般情况(例如处理文件截断等),您可以使用 tellg/seekg。

我试过你的代码,它工作正常。

使用以下命令编译代码:

g++ main.cpp -o testmain

我打开了两个终端: 在一个终端上首先创建 temp.txt & 运行 应用程序 testmain。 从另一个 运行 echo 命令,它可以正常工作。

你想实现这个或者你尝试了别的东西...

很可能 cout 缓冲区在您的测试中没有刷新,因为缓冲区大小没有达到溢出限制。 您可以尝试通过执行 std::cout << line << std::endl; 而不是 std::cout << line << "\n"; 或在 sleep(1); 之前调用 std::cout.flush()l 来刷新缓冲区。这两种方式都应该与 clang 和 gcc 一起可靠地工作。

这些问题的答案很好地解释了缓冲:

C++ cout and cin buffers, and buffers in general

Strange behaviour of std::cout in Linux

尝试在 sleep 之后调用 ifs.sync()。我能够使用您发布的代码重现您的问题,这一更改为我解决了这个问题。

这里也有一个明显的重复clang 3.3/Xcode & libc++: std::getline does not read data after calling ifstream::clear()