Bil*_*ard 1 c++ linux operating-system system-calls
我正在使用以下代码尝试df在Linux中读取命令的结果popen.
#include <iostream> // file and std I/O functions
int main(int argc, char** argv) {
FILE* fp;
char * buffer;
long bufSize;
size_t ret_code;
fp = popen("df", "r");
if(fp == NULL) { // head off errors reading the results
std::cerr << "Could not execute command: df" << std::endl;
exit(1);
}
// get the size of the results
fseek(fp, 0, SEEK_END);
bufSize = ftell(fp);
rewind(fp);
// allocate the memory to contain the results
buffer = (char*)malloc( sizeof(char) * bufSize );
if(buffer == NULL) {
std::cerr << "Memory error." << std::endl;
exit(2);
}
// read the results into the buffer
ret_code = fread(buffer, 1, sizeof(buffer), fp);
if(ret_code != bufSize) {
std::cerr << "Error reading output." << std::endl;
exit(3);
}
// print the results
std::cout << buffer << std::endl;
// clean up
pclose(fp);
free(buffer);
return (EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
此代码是给我一个"内存错误"与"2"的退出状态,所以我可以看到哪里它的失败,我只是不明白为什么.
我把它放在Ubuntu论坛和C++参考中找到的示例代码中,所以我没有和它结婚.如果有人可以建议一种更好的方式来阅读system()调用的结果,我会接受新的想法.
编辑到原文:好的,bufSize现在是负面的,现在我理解为什么.您无法随意访问管道,因为我天真地试图这样做.
我不能成为第一个尝试这样做的人.有人可以给(或指向我)一个如何在C++中读取system()调用结果的示例吗?
你这太难了. popen(3)FILE *为标准管道文件返回一个常规旧文件,也就是说,换行符终止记录.您可以使用C中的fgets(3)以非常高的效率读取它:
#include <stdio.h>
char bfr[BUFSIZ] ;
FILE * fp;
// ...
if((fp=popen("/bin/df", "r")) ==NULL) {
// error processing and return
}
// ...
while(fgets(bfr,BUFSIZ,fp) != NULL){
// process a line
}
Run Code Online (Sandbox Code Playgroud)
在C++中它更容易 -
#include <cstdio>
#include <iostream>
#include <string>
FILE * fp ;
if((fp= popen("/bin/df","r")) == NULL) {
// error processing and exit
}
ifstream ins(fileno(fp)); // ifstream ctor using a file descriptor
string s;
while (! ins.eof()){
getline(ins,s);
// do something
}
Run Code Online (Sandbox Code Playgroud)
那里有更多的错误处理,但这就是主意.问题的关键是,你对待FILE *来自POPEN就像任何 FILE *,和逐行阅读.