【问题标题】:C++ system() function — How to collect the output of the issued command?C++ system() 函数 — 如何收集发出的命令的输出?
【发布时间】:2026-01-21 04:00:02
【问题描述】:

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

int system ( const char * command );

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

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

【问题讨论】:

  • 我认为他的意思是评论返回的字符串,即stdout。
  • 是的,我的意思是发出的命令返回的字符串
  • 请注意,system() 函数(以及接受的答案中建议的 popen()pclose() 函数)也适用于 C。我没有对这个问题进行双重标记(通常用 C 和 C++ 进行双重标记不是一个好主意),但这可能是规则的一个例外。

标签: c++ popen


【解决方案1】:

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

如果是后者,请改用popen()pclose()

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

【讨论】:

  • 感谢您的提示 - 我将尝试使用 popen()
  • 从 stdout/stderr 被传递到父级 stdout/stderr 的意义上来说,系统不只是一个 passthru 调用吗?
  • @David:是的,但是 OP 不希望它通过。他想在他的程序中将它收集到一个字符串中
【解决方案2】:

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

我相信 system() 将返回的确切细节是特定于系统的。

【讨论】:

  • 它们确实是:7.20.4.6 系统函数:如果参数是空指针,则系统函数仅在命令处理器可用时才返回非零值。如果参数不是空指针,并且系统函数确实返回,它返回一个实现定义的值
  • 我不需要system()的返回值——我想收集下发命令的返回字符串...
  • 您认为系统会返回什么?它返回命令的返回值。
  • 那个 int 的值是命令的返回值。也许您的意思是您想将输出收集到标准输出等流之一?
  • @mspoerr:我认为您需要解释“发出命令的返回值”,因为您似乎以非常规的方式使用“返回值”(如果它不是 你所追求的 int )。如果您真的不知道如何将 int 存储在变量中,那么我们在沟通方面会遇到更深层次的问题。
【解决方案3】:

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

对于接收状态码,只需检查system函数的返回值。

为了接收输出,要么将其重定向到一个文件中,然后读取该文件,要么使用popen

【讨论】:

    【解决方案4】:

    system 的返回值(讽刺地)取决于系统,但在 POSIX 系统(包括 Linux 等)中,它与 wait 相同——低 8 位或 16 位是孩子(可能是“返回的值”的意思),较高的位表示终止孩子的信号类型(如果有)。我提供的联机帮助页的 URL 提供了预处理器宏,您可以使用它来撬开返回值!

    没有程序的“返回字符串”之类的东西,正如您现在在评论中阐明的那样,这是您想要的;作为已经提到的另一个答案,如果您想要由其他程序获取 输出 的文本,您应该使用 popen 而不是 system

    【讨论】:

      【解决方案5】:

      受 bmorin 尝试的启发,但工作和测试,这个 sn-p 将接受一个 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*,因此代码无法编译。也许最令人震惊的是,它在返回结果之前释放了结果。)

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

            这是一段代码 sn-p(纯 C 语言)执行带有popen 的命令并返回其输出:

            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;
            }
            

            【讨论】:

              最近更新 更多