当前位置:  开发笔记 > 编程语言 > 正文

如何在C++中读取system()调用的结果?

如何解决《如何在C++中读取system()调用的结果?》经验,为你挑选了2个好方法。

我正在使用以下代码尝试df在Linux中读取命令的结果popen.

#include  // 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);
}

此代码是给我一个"内存错误"与"2"的退出状态,所以我可以看到哪里它的失败,我只是不明白为什么.

我把它放在Ubuntu论坛和C++参考中找到的示例代码中,所以我没有和它结婚.如果有人可以建议一种更好的方式来阅读system()调用的结果,我会接受新的想法.

编辑到原文:好的,bufSize现在是负面的,现在我理解为什么.您无法随意访问管道,因为我天真地试图这样做.

我不能成为第一个尝试这样做的人.有人可以给(或指向我)一个如何在C++中读取system()调用结果的示例吗?



1> Charlie Mart..:

你这太难了. popen(3)FILE *为标准管道文件返回一个常规旧文件,也就是说,换行符终止记录.您可以使用C中的fgets(3)以非常高的效率读取它:

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

在C++中它更容易 -

#include 
#include 
#include 

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
}

那里有更多的错误处理,但这就是主意.问题的关键是,你对待FILE *来自POPEN就像任何 FILE *,和逐行阅读.



2> CesarB..:

为什么会std::malloc()失败?

显而易见的原因是"因为std::ftell()返回了一个带负号的符号,后来被视为一个巨大的无符号数".

根据文档,std::ftell()失败时返回-1.它失败的一个明显原因是你不能在管道或FIFO中寻找.

跑不了的; 如果不读取它就无法知道命令输出的长度,并且只能读取一次.您必须以块的形式阅读它,或者根据需要增长缓冲区或者动态解析.

但是,当然,您可以通过直接使用系统调用来避免整个问题,df可能用于获取其信息:statvfs().

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有