2016-10-28 8 views
1

私は可変出力の単一の巨大な行を印刷するbashスクリプトを持っています。 私が見たすべての例では、1行ずつ読み込むために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()'を使う方があなた自身で行うよりも確実です。行が1024以上であれば、あなたの現在のコードは次のfgets()の呼び出し(S)で行の残りの部分を読むことを続けること –

+2

は注意。したがって、テキストを単に出力する現在のコードは問題なく動作します。魔法のように – 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

関連する問題