fgets 无法在 Ubuntu 20.04 上从管道读取两次
fgets not able to read from pipe twice on Ubuntu 20.04
我有以下用于 Ubuntu 18.04 的代码。现在,我在 Ubuntu 20.04 中编译并 运行 它,并且由于某种原因,代码停止工作。
该代码旨在从命名管道中读取。为了测试它,我用 mkfifo /tmp/pipe
创建管道,然后用 echo "message" >> /tmp/pipe
.
写入管道
第一次执行fgets()
方法,函数returns管道中的期望值;但是从第二次调用开始,方法 returns NULL
和代码卡在循环中,即使我执行了几个 echo 命令。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <sstream>
#include <fstream>
#include <limits>
#include <iomanip>
#include <iostream>
#include <cstdlib>
using namespace std;
FILE* result_pipe_stream;
string read_result_from_pipe(){
if (result_pipe_stream == NULL){
printf("\n[BINDING-COMMONS] ERROR: Pipe is not set");
return NULL;
}
std::stringstream oss;
while (1) {
char buf[BUFSIZ];
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL ) {
int buflen = strlen(buf);
if (buflen >0){
if (buf[buflen-1] == '\n'){
buf[buflen-1] = '[=11=]';
oss << buf;
return oss.str();
} else {
oss << buf;
// line was truncated. Read another block to complete line.
}
}
}
}
}
int main(int argc, char *argv[]){
result_pipe_stream = fopen("/tmp/pipe" , "r");
while (1){
cout << read_result_from_pipe() << '\n';
}
}
- 为什么代码不再有效?我假设某些库在发行版中发生了变化,并且 fgets 不再能够从管道中正确读取
- 我该如何解决这个问题?
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL )
--> 一旦fgets()
returns NULL
由于文件结束,将继续return NULL
在随后的调用中 没有读取 除非清除 result_pipe_stream
的 文件结束指示器 - 就像 clearerr()
.代码陷入无限循环,不再阅读,应该。
真正的问题是为什么它在 Ubuntu 18.04 中“有效”。我怀疑那个版本不兼容。
while (1) {
char buf[BUFSIZ];
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL ) {
...
}
// Perhaps assess why here, end-of-file, input error, too often here, ...
clearerr(result_pipe_stream); // add
}
我有以下用于 Ubuntu 18.04 的代码。现在,我在 Ubuntu 20.04 中编译并 运行 它,并且由于某种原因,代码停止工作。
该代码旨在从命名管道中读取。为了测试它,我用 mkfifo /tmp/pipe
创建管道,然后用 echo "message" >> /tmp/pipe
.
第一次执行fgets()
方法,函数returns管道中的期望值;但是从第二次调用开始,方法 returns NULL
和代码卡在循环中,即使我执行了几个 echo 命令。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <sstream>
#include <fstream>
#include <limits>
#include <iomanip>
#include <iostream>
#include <cstdlib>
using namespace std;
FILE* result_pipe_stream;
string read_result_from_pipe(){
if (result_pipe_stream == NULL){
printf("\n[BINDING-COMMONS] ERROR: Pipe is not set");
return NULL;
}
std::stringstream oss;
while (1) {
char buf[BUFSIZ];
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL ) {
int buflen = strlen(buf);
if (buflen >0){
if (buf[buflen-1] == '\n'){
buf[buflen-1] = '[=11=]';
oss << buf;
return oss.str();
} else {
oss << buf;
// line was truncated. Read another block to complete line.
}
}
}
}
}
int main(int argc, char *argv[]){
result_pipe_stream = fopen("/tmp/pipe" , "r");
while (1){
cout << read_result_from_pipe() << '\n';
}
}
- 为什么代码不再有效?我假设某些库在发行版中发生了变化,并且 fgets 不再能够从管道中正确读取
- 我该如何解决这个问题?
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL )
--> 一旦fgets()
returns NULL
由于文件结束,将继续return NULL
在随后的调用中 没有读取 除非清除 result_pipe_stream
的 文件结束指示器 - 就像 clearerr()
.代码陷入无限循环,不再阅读,应该。
真正的问题是为什么它在 Ubuntu 18.04 中“有效”。我怀疑那个版本不兼容。
while (1) {
char buf[BUFSIZ];
if( fgets (buf, BUFSIZ, result_pipe_stream) != NULL ) {
...
}
// Perhaps assess why here, end-of-file, input error, too often here, ...
clearerr(result_pipe_stream); // add
}