在C语言中提取dos命令输出

4

使用system()或者exec(),我可以执行任何命令,但是它们会将结果显示在控制台中。我想执行这个命令,然后提取输出并处理它,最后再显示出来。在Windows/DOS平台上我该怎么做呢?


3个回答

6
在标准C中没有这样的东西,但通常为了与POSIX兼容,编译器会实现popen(VC++中的_popen),它会启动一个命令(就像使用system一样),并返回一个FILE *到你要求的流(如果你想读取输出,可以请求stdout;如果你想给程序输入一些内容,可以请求stdin)。
一旦你获得了FILE *,你就可以像在普通文件上一样使用fread/fscanf/...来读取它。
如果你想同时进行输入和输出重定向,事情就变得有点复杂了,因为Windows编译器通常确实有类似于POSIX的pipe,但它并不完全兼容(主要是因为Windows的进程创建模型不同)。
在这种情况下(以及任何需要比普通的popen更多控制已启动进程的情况下),我会简单地使用Windows上执行IO重定向的“真实”方法,即使用CreateProcess和适当的选项;例如,请参见此处

非常棒的答案。+1……也看看我的回答吧……它以更简单的方式解决了问题。 - Tabrez Ahmed
@ahmedtabrez:谢谢你,但我不建议使用你的方法,因为它涉及文件IO(带有所有缺点:权限、已存在的文件、处理错误等),而这并不是必要的。 - Matteo Italia

2

Matteo Italia的答案很棒。但是有些编译器(特别是旧版本)不支持popen()

如果不支持popen(),这里提供一种可能的解决方案。

在DOS中,我们可以使用>将输出重定向到临时文件。

例如:

C:\> ipconfig > temp.txt

我可以在我的C代码中打开 temp.txt ,然后重新处理它的内容。

我用于此的C代码大致如下:

system("ipconfig > temp.txt");
FILE *fp;
fp = fopen("temp.txt","r");
//                                         //
//... Code for reprocessing can go here ...//
//                                         //

1

对于那些没有popen的人,这里有一个替代答案,应该可以在大多数系统上工作。这段代码不是线程安全的。我认为这对大多数情况来说不是一个重要的限制。

#include <stdio.h>
#include <process.h>
#include <io.h>
#include <sys\stat.h>
#include <assert.h>

int main()
{
    int so = dup(1);
    close(1);
    int i = creat("output.txt", S_IWRITE);
    assert(i == 1); // i should be 1...
    system("dir");
    close(i);
    dup2(so, 1);
    close(so);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接