2016-10-28 83 views
1

我有一個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()命令閱讀來處理它?

+0

你可以使用POSIX ['getline()'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html)來閱讀儘可能長的一行,但只限於內存限制,或者你可以當你還沒有收到換行符時,反覆調用fgets(),添加一個你根據需要動態分配的緩衝區。這兩者都不是很複雜,儘管使用getline()比使用getline()更容易。 –

+2

請注意,如果一行超過1024行,您當前的代碼將繼續在下一個fgets()調用中讀取該行的其餘部分。因此,只需打印出文本的當前代碼就可以毫無問題地工作。 (然而,如果你想在你的程序中存儲一整行並且在一段時間內操作該行 - 你需要看看alk的答案) – nos

回答

2

但如果我不知道,如果輸出線的長度更大的1024個字節

然後您需要處理傳入的數據動態存儲。

要做到這一點,你會額外地顯示你添加一個動態分配的「字符串」,如果通過重新分配來提供更多空間而被充分使用,它將會增長。

代碼這樣做可能是這樣的:

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

清理打開的文件描述符和動態分配的內存中的任何故障的情況下作爲練習留給讀者...... ;-)

+0

作品就像一個魅力!謝謝@alk! – harrison4

相關問題