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()
我试图用 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()