我如何分配可变长度的命令输出?

How could I allocate a variable length command output?

我有一个 bash 脚本,它打印一行巨大的变量输出。 我见过的所有示例都使用 1024 字节左右的固定缓冲区,以便逐行读取。

#include <stdio.h>
#include <stdlib.h>

int main( int argc, char *argv[] ) {

  FILE *fp;
  char path[1024];

  /* Open the command for reading. */
  fp = popen("bash /home/ouhma/myscript.sh", "r");
  if (fp == NULL) {
    printf("Failed to run command\n" );
    exit(1);
  }

  /* Read the output a line at a time - output it. */
  while (fgets(path, sizeof(path)-1, fp) != NULL) {
    printf("%s", path);
  }

  /* close */
  pclose(fp);

  return 0;
}

Link参考:C: Run a System Command and Get Output?

但是如果我不知道输出行的长度是否大于 1024 字节怎么办? 我如何通过使用 popen() 命令读取来处理它?

But what if I don't know if the output line has a length even bigger of 1024 bytes

然后您需要动态地处理传入数据的存储。

为此,您还需要在显示的内容中添加一个动态分配的 "string",如果通过重新分配它来提供更多空间来充分使用它,它会增长。

这样做的代码可能如下所示:

#include <stdlib.h>
#include <stdio.h>


#define BUFFER_SIZE (1024)
#define START_SIZE (1) /* Has to be > 0 */


int main(void) 
{
  size_t s = START_SIZE;
  char * path = malloc(s);
  if (NULL == path)
  {
    perror("malloc() failed");
    return EXIT_FAILURE);
  }

  path[0] = '[=10=]';

  {
    /* Open the command for reading. */
    FILE * fp = popen("bash /home/ouhma/myscript.sh", "r");
    if (NULL == fp) 
    {
      perror("popen() failed");
      return EXIT_FAILURE); /* By returning here the code leaks the memory
                               already allocated to path as well as fp. */
    }

    {
      char buffer[BUFFER_SIZE];

      /* Read the output a line at a time - output it. */
      while (NULL != fgets(buffer, sizeof buffer, fp)) 
      {
        fprintf(stderr, "partly read: '%s'\n", buffer);

        while ((s - 1) < strlen(buffer))
        {
          void * p = realloc(path, s *= 2); /* Grow s exponentially. */
          if (NULL == p)
          {
            perror("realloc() failed");
            return EXIT_FAILURE; /* By returning here the code leaks the memory
                                    already allocated to path as well as fp. */
          }

          path = p;
        }

        /* Concatenate what just had been read to final "string". */
        strcat(path, buffer);
      }
    }

    if (!feof(fp))
    {
      perror("fgets() failed");
    }

    /* Close file. */
    if (-1 == pclose(fp))
    {
      perror("pclose() failed");
    }
  }

  /* Print result. */
  printf("read: '%s'\n", path);

  /* Clean up. */
  free(path);

  return EXIT_SUCCESS;
}

清理打开的文件描述符和动态分配的内存以防出现任何故障留给 reader ... ;-)

作为练习