2016-09-08 8 views
2
/* Utility function to read lines of unknown lengths */ 
char *readline(FILE* fp, int max_length) 
{ 
    //The size is extended by the input with the value of the provisional 
    char *str; 
    int ch; 
    int len = 0; 
    int current_max = max_length; 

    str = (char*)malloc(sizeof(char)*current_max); 
    if(!str) 
     return str; 

    while((char)(ch = fgetc(fp))!='\n' && ch != EOF) 
    { 
     str[len++] = ch; 
     if(len == current_max) 
     { 
      current_max = current_max + max_length; 
      str = realloc(str, sizeof(char)*current_max); 
      if(!str) 
       return str; 
     } 
    } 
    str[len] = '\0'; 

    return str; 
} 

私は未知の長さの行を読み取るために上記のコードスニペットを持っています。私はstdinから期待されるように、単一行の入力を読むことができますが、ファイルを読んでいる間にファイルのEOFを決定するのに問題があります。不明な行の長さのファイルを読み取っているときにEOFを確認する

ファイルから読み込んでいるときに、私はそれをループで1行ずつ読み込んでいますが、今度はすべての行が読み込まれたらループを中断したいのですが、いつ実行するのか判断できません。永遠に実行を終了します。休憩状態を判断するのに手伝ってください。

char *line; 

while(1) 
{ 
    line = readline(fd, MAX_INPUT_LENGTH); 

    /*IF all lines have been read then break off the loop, basically determine EOF ?* 

    //text processing on the line 

} 
+0

[malloc()の戻り値と 'C 'のファミリをキャストしない理由についてのこの記事を参照してください。](http://stackoverflow.com/q/605845/2173917)。 –

+4

問題は、ファイルの終わりに到達したことを関数が呼び出し側にどのように伝えることができるのかわからないことです。文字が正常に読み取られる前にEOFが検出された場合は、NULLを戻すことを検討してください。 –

+1

'while'のキャストは不要です(' '\ n''は 'int'です)。私は通常、どちらの命令も動作しますが、while((ch = fgetc(fp))!= EOF && ch!= '\ n')を使用します。 –

答えて

0

試してみてください。

while((ch = fgetc(fp))!=EOF) 
{ 
    str[len++] = ch; 
    if (ch=='\n') 
     break; 
} 
str[len]= '\0'; 
return(str); 

これはEOLがEOFの扱いから取り扱い離れます。 EOFを読み込んだら、readlineの次の呼び出しは、空の文字列、つまりEOFに達したという信号を返します。

+1

このアプローチでは、\ n "'と 'EOF'のような行を区別することはありません。どちらも空の文字列を返します。 – chux

+0

@chux、良い点。 –

+0

候補簡素化: 'if(ch == '\ n'){ str [len ++] = '\ n'; str [len] = '\ 0'; return(文字列); } str [len ++] = ch; ' - >' str [len ++] = ch; if(ch == '\ n'){break; } ' – chux

0

あなたはコードをこのように変更する必要があります。

char *line; 
    int eofreached; // pay attention 
    eofreached = 0;// pay attention 
while(eofreached == 0)// pay attention 
{ 
    line = readline(fd, MAX_INPUT_LENGTH, &eofreached);// pay attention 

    /*IF all lines have been read then break off the loop, basically determine EOF ?* 

    //text processing on the line 

} 

/* Utility function to read lines of unknown lengths */ 
char *readline(FILE* fp, int max_length, int* eof_found)// pay attention 
{ 
    //The size is extended by the input with the value of the provisional 
    char *str; 
    int ch; 
    int len = 0; 
    int current_max = max_length; 

    str = (char*)malloc(sizeof(char)*current_max); 
    if(!str) 
     return str; 

    while((char)(ch = fgetc(fp))!='\n' && ch != EOF) 
    { 
     str[len++] = ch; 
     if(len == current_max) 
     { 
      current_max = current_max + max_length; 
      str = realloc(str, sizeof(char)*current_max); 
      if(!str) 
       return str; 
     } 
    } 
    if (ch == EOF) // pay attention // this line and next line 
     *eof_found = 1; // pay attention // can be improved: *eof_found = ch == EOF 
    str[len] = '\0'; 

    return str; 
} 
0

これを処理するための最良の方法は、readline戻りEOFのためのNULL [またはエラー]を持つことです。しかし、空白行についても考慮する必要があります。

私はあなたのコードを変更し、私が動作すると思うものに注釈を付けました。 max_lengthは[無償スタイルのクリーンアップをご容赦ください]理由reallocが行われた方法への変更として有用ではありませんでした:

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

/* Utility function to read lines of unknown lengths */ 
// RETURNS: string pointer (NULL means EOF or realloc failure) 
char * 
readline(FILE *fp,int max_length) 
{ 
    // The size is extended by the input with the value of the provisional 
    char *str; 
    char *tmp; 
    int ch; 
    int len = 0; 
    int current_max = 0; 

    // assume we'll get EOF 
    str = NULL; 

    while (1) { 
     ch = fgetc(fp); 
     if (ch == EOF) 
      break; 

     // enable this if you want to absorb blank lines invisibly 
#if 0 
     if (ch == '\n') 
      break; 
#endif 

     // grow the buffer 
     if (len == current_max) { 
      // this "grow length" can be any amount 
      current_max += 10; 

      tmp = str; 
      str = realloc(tmp,current_max + 1); 

      if (str == NULL) { 
       free(tmp); 
       break; 
      } 
     } 

     // check for newline 
     // NOTE: do this _after_ the realloc to differentiate a blank line 
     // from EOF 
#if 1 
     if (ch == '\n') 
      break; 
#endif 

     str[len++] = ch; 
    } 

    // trim string to exact length and add EOS to string 
    // NOTE: the trim is optional -- without it, it just means the buffer may 
    // be slightly larger than needed 
    if (str != NULL) { 
#if 1 
     tmp = str; 
     str = realloc(str,len + 1); 
     if (str == NULL) 
      free(tmp); 
     else 
      str[len] = 0; 
#else 
     str[len] = 0; 
#endif 
    } 

    return str; 
} 
0

はループが停止した理由をテストすることをお勧めします。

メモリ管理が省略されています。

while((ch = fgetc(fp)) != '\n' && ch != EOF) { 
    str[len++] = ch; 
} 

// If _nothing_ read, return NULL 
if (len == 0 && ch == EOF) { 
    return NULL; 
} 

str[len]= '\0'; 
return str; 
関連する問題