9

I was trying to write a code in C++ the does something like tail -f in linux. I found this question : How to read a growing text file in C++? and implemented the same. I created a temp.txt and started doing echo "temp" >> temp.txt. But my program is not printing the updates made to the file .What am I doing wrong? This is the code I'm using

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

UPDATE

I've tried the same code on a linux machine and it was working fine, but it is not working on Mac. I was using gcc to compile the code.

gcc -v gives

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

UPDATE 2
I've investigated further and realised that I was not using gcc after all. I've installed gcc separately and it is working fine now. Is this a bug in clang?

Community
  • 1
  • 1
banarun
  • 2,305
  • 2
  • 23
  • 40

4 Answers4

2

It is quite possible that cout buffer did not flush in your tests because buffer size did not reach the overflow limit. You could try flushing the buffer by either doing std::cout << line << std::endl; instead of std::cout << line << "\n"; or calling std::cout.flush()l before sleep(1);. Both ways should work reliably with clang and gcc.

Answers to these questions explain buffering really well:

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

Strange behaviour of std::cout in Linux

Community
  • 1
  • 1
daniq
  • 151
  • 4
1

I have tried with your code and it is working fine.

Compiled code using following command:

g++ main.cpp -o testmain

I have open two terminal: On one terminal first create temp.txt & run application testmain. and from another one run echo command and it would working fine.

run application

enter image description here

You want achieved this or you tried for something else...

Dipak D Desai
  • 867
  • 1
  • 8
  • 20
1

Try calling ifs.sync() after sleep. I was able to reproduce your problem with the code you posted, and this change solved it for me.

There is also an apparent duplicate here clang 3.3/Xcode & libc++: std::getline does not read data after calling ifstream::clear()

Community
  • 1
  • 1
antron
  • 3,749
  • 2
  • 17
  • 23
0

The following works when appending to a file.

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

For the general case (e.g. handling file truncation etc), you could work with tellg/seekg.

Tasos Vogiatzoglou
  • 2,393
  • 12
  • 16