C++ system() 函数如何收集发出命令的输出?

发布于 2024-08-07 21:28:58 字数 197 浏览 7 评论 0 原文

我正在使用 C++ system() 函数运行一些命令:

int system ( const char * command );

如何从发出的命令中收集标准输出?

具体来说,我想收集发出的命令的输出(例如,发出 dir 命令的目录列表输出)。

I'm running some commands with the C++ system() function:

int system ( const char * command );

How can I collect the standard output from the issued commands?

To be specific, I want to collect the output of the issued command (for example, the directory listing output from issuing the dir command).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

红焚 2024-08-14 21:28:59

以下是使用 popen 执行命令并返回其输出的代码片段(纯 C 语言):

char* exec(const char* command) {
    FILE* fp;
    char* result = NULL;
    size_t len = 0;

    fflush(NULL);
    fp = popen(command, "r");
    if (fp == NULL) {
        printf("Cannot execute command:\n%s\n", command);
        return;
    }

    while(getline(&result, &len, fp) != -1) {
        fputs(result, stdout);
    }

    free(result);
    fflush(fp);
    if (pclose(fp) != 0) {
        perror("Cannot close stream.\n");
    }
    return result;
}

Here is a code snippet (in plain C) executing a command with popen and returning its output:

char* exec(const char* command) {
    FILE* fp;
    char* result = NULL;
    size_t len = 0;

    fflush(NULL);
    fp = popen(command, "r");
    if (fp == NULL) {
        printf("Cannot execute command:\n%s\n", command);
        return;
    }

    while(getline(&result, &len, fp) != -1) {
        fputs(result, stdout);
    }

    free(result);
    fflush(fp);
    if (pclose(fp) != 0) {
        perror("Cannot close stream.\n");
    }
    return result;
}
天气好吗我好吗 2024-08-14 21:28:58

您是否正在寻找执行命令的返回值(如“退出状态”),或其输出(如“它打印了什么”)?

如果是后者,请使用 popen()pclose() 代替。

如果是前者,请查看 system() 的返回值(并使用 waitpid() 来解释它)。

Are you looking for returned value (as in "exit status") of the executed command, or for its output (as in "what did it print")?

If the latter, use popen() and pclose() instead.

If the former, look at the return value from system() (and use the documentation for waitpid() to interpret it).

Oo萌小芽oO 2024-08-14 21:28:58

system() 返回一个 int,所以只需抓住它: int rvalue = system(command);

我相信什么 system( ) 将返回的内容是特定于系统的。

system() returns an int, so just grab it: int rvalue = system(command);

I believe the exact details of what system() will return are system-specific, though.

灯角 2024-08-14 21:28:58

受到 bmorin 尝试的启发,但经过工作和测试,此代码片段将采用 char* 命令并返回包含执行该命令的结果的 char*...

// Calling function must free the returned result.
char* exec(const char* command) {
  FILE* fp;
  char* line = NULL;
  // Following initialization is equivalent to char* result = ""; and just
  // initializes result to an empty string, only it works with
  // -Werror=write-strings and is so much less clear.
  char* result = (char*) calloc(1, 1);
  size_t len = 0;

  fflush(NULL);
  fp = popen(command, "r");
  if (fp == NULL) {
    printf("Cannot execute command:\n%s\n", command);
    return NULL;
  }

  while(getline(&line, &len, fp) != -1) {
    // +1 below to allow room for null terminator.
    result = (char*) realloc(result, strlen(result) + strlen(line) + 1);
    // +1 below so we copy the final null terminator.
    strncpy(result + strlen(result), line, strlen(line) + 1);
    free(line);
    line = NULL;
  }

  fflush(fp);
  if (pclose(fp) != 0) {
    perror("Cannot close stream.\n");
  }
  return result;
}

我研究了仅编辑 bmorin 的代码,但必须更改大多数行,所以单独的答案似乎更合适。如果没有,抱歉。 (除其他问题外,bmorin 的代码实际上并没有累积这些行;它将它们打印到标准输出,我认为它们不会被需要,因为 system() 会这样做;并且它在一个错误路径中返回 void,当函数必须返回一个 char*,因此代码无法编译。也许最令人震惊的是,它在返回结果之前释放了结果。)

Inspired by bmorin's attempt, but working and tested, this snippet will take a char* command and return a char* containing the results of executing that command...

// Calling function must free the returned result.
char* exec(const char* command) {
  FILE* fp;
  char* line = NULL;
  // Following initialization is equivalent to char* result = ""; and just
  // initializes result to an empty string, only it works with
  // -Werror=write-strings and is so much less clear.
  char* result = (char*) calloc(1, 1);
  size_t len = 0;

  fflush(NULL);
  fp = popen(command, "r");
  if (fp == NULL) {
    printf("Cannot execute command:\n%s\n", command);
    return NULL;
  }

  while(getline(&line, &len, fp) != -1) {
    // +1 below to allow room for null terminator.
    result = (char*) realloc(result, strlen(result) + strlen(line) + 1);
    // +1 below so we copy the final null terminator.
    strncpy(result + strlen(result), line, strlen(line) + 1);
    free(line);
    line = NULL;
  }

  fflush(fp);
  if (pclose(fp) != 0) {
    perror("Cannot close stream.\n");
  }
  return result;
}

I looked into just editing bmorin's code, but would have had to change most lines, so a separate answer seemed more appropriate. Apologies if not. (Amongst other problems, bmorin's code didn't actually accumulate the lines; it printed them to stdout, where I presume they would not be wanted, since system() would have done that; and it returned void in one error path, when the function must return a char*, so the code wouldn't compile. Perhaps most egregious, it freed the result just before returning it.)

百善笑为先 2024-08-14 21:28:58

系统程序通常有两种“返回”值的方法:写入标准输出,以及在程序末尾返回状态整数。 (通常有更多方法返回结果,例如通过写入文件或数据库,但我认为这些超出了此处的范围)。

要接收状态码,只需检查system函数的返回值即可。

要接收输出,请将其重定向到文件中,然后读取该文件,或者使用 popen

There are typically two ways for a system program to "return" a value: by writing to stdout, and by returning a status integer at the end of the program. (there are often more ways to return results, eg. by writing to a file or into a database, but I assume those are out of scope here).

For receiving the status code, just check the return value of the system function.

For receiving the output, either redirect it into a file, and read the file afterwards, or use popen.

撞了怀 2024-08-14 21:28:58

system 的返回值(讽刺的是)与系统相关,但在 POSIX 系统(包括 Linux 等)中,它与 wait -- 低 8 位或 16 位是子进程的退出状态(可能是您所说的“返回值”的意思),高位表示什么某种信号终止了孩子,如果有的话。我给出的联机帮助页的 URL 提供了预处理器宏,您可以使用它来撬开该返回值!

不存在程序的“返回字符串”之类的东西,正如您现在在评论中澄清的那样,这是您想要的;正如已经提到的另一个答案,如果您希望其他程序获得输出的文本,您应该使用popen而不是system

The return value of system is (ironically) system-dependent, but in POSIX systems (including Linux, etc), it's the same as for wait -- low 8 or 16 bits are the exit status of the child (probably what you mean by "value returned by"), higher bits indicating what kind of signal terminated the child, if any. The URL to the manpage I've given supplies the preprocessor macros you can use to pry apart that return value!

There is no such thing as a "return string" of a program, as you've now clarified in a comment is what you desire; as another answer already mentioned, if you want the text which gets output by the other program, you should use popen instead of system.

苦妄 2024-08-14 21:28:58

system() 被声明并且在 libc 中定义。您可以阅读我提供的第一个链接,也可以在 shell 中的命令提示符处执行 man system 操作。

system() is declared and defined in libc. You can either read the first link I provided, or do man system at a command prompt in your shell.

终止放荡 2024-08-14 21:28:58

我建议使用 popen() 函数,正如其他人所说,
但这个问题是特定于平台的。 popen() 函数是
在使用 POSIX API 的操作系统上可用。我不是
确定此命令是否适用于其他 API(例如 WIN32)

I suggest the popen() functions, as said by other people as well,
but this problem is platform specific. the popen() function is
available on operating systems that use the POSIX API. I am not
sure if this command would work on other APIs like WIN32

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文