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

标签 c file-io malloc dynamic-memory-allocation

我有一个 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;
}

链接引用:C: Run a System Command and Get Output?

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

最佳答案

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

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

要做到这一点,您还需要在显示的内容中添加一个动态分配的“字符串”,如果通过重新分配它来提供更多空间来充分使用它,该字符串就会增长。

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

#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] = '\0';

  {
    /* 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;
}

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

关于c - 我如何分配可变长度的命令输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40299798/

相关文章:

多处理器系统上的临界区和内存栅栏/屏障

c++ - 编译时 off_t 的大小

ruby - 在 Mac OS X 上调试 Ruby 中的 malloc 错误

c - 为什么我需要标题?

c - Linux 用户空间程序的正确构建环境

命令如 1;和2c1;在 shell 上

c++ - 从文件读取输入打印出奇怪的符号

c++ - 连接文件而不复制其内容

c - 在 C 中的自制字符串结构中使用 realloc - 可能存在内存泄漏?

c++ - 使用 malloc() 分配的指针实例化一个类