0

信じられないほど単純であるべきことは、私を困惑させました。私がやっているのはgetLine、行をバッファに読み込むメソッドを書いていることだけです。から始まるバッファーにメモリを割り当て10 bytes、次にfgetschar 配列に割り当てます。アイデアは、行全体を取得するまで、バッファーのサイズを 2 倍にして、これを何度も試行することです。ただし、私が観察しているように見えるのは、行の一部を読み取り、次の試行で最後の試行でスペースが不足した場所を続行するため、行の最後の部分を提供することです。何が間違っているかについての洞察はrealloc、バッファへの私の記憶で期待していますが、大歓迎です。

char * mygetline( char **buffer,  FILE * infile )
{
    int buffSiz = 10;
    *buffer = calloc( buffSiz, 1 );
    do
    {
        char * result = fgets(*buffer, sizeof *buffer ,infile);
        if(result == NULL)
        {
            free(buffer);
            return NULL;
        }

        if(strchr(*buffer, '\n'))
            return *buffer;
        else
        {
            char *newBuf;
            buffSiz = buffSiz*2;
            newBuf = realloc(NULL, buffSiz);
            char *buffer = newBuf;
            printf("%d", buffSiz);
            printf("%s", *buffer);
        }
    } while (1);  // INFINITE LOOP - WE ONLY GET OUT BY RETURNING FROM WITHIN
4

3 に答える 3

4

複数の欠陥があります。

  • sizeof *bufferそれはポインタであるため、あなたが望むことをしません。buffSiz代わりに使用する必要があります

  • char *buffer = newBuf;新しいメモリをローカル変数に割り当てています。つまり、elseが終了すると消える変数です。

  • にバッファを渡していないrealloc、常に渡しているNULL

  • あなたはのリターンをチェックしていませんrealloc

恥知らずな自己宣伝として、別の回答に投稿した関数を次に示します。

于 2013-02-01T07:51:51.183 に答える
3

それがファイル関数の仕組みです。最初にファイルの位置を取得してから、新しい読み取りを試行するたびに位置をリセットする必要があります。

関数で現在位置を取得し、ftell関数で位置を設定できfseekます。


それを行う代わりに (位置を取得し、ファイル位置を一定に再配置する)、realloc渡されたバッファーを再割り当てし、読み取り関数が次の部分を読み取るという事実と一緒に内容を保持するという事実を使用してみませんか? その場合、次に読み取る場所へのポインターが必要です。改行がない場合は、ポインターを再割り当てして進めるだけですか?

このようなもの:

char *readpos = *buffer;
size_t readsize = bufSize;

while (1)
{
    char *p = fgets(readpos, readsize, infile);
    if (!p)
        break;  /* Error */

    /* Search from the end, as there's where the newline should be */
    if (strrchr(p, '\n') != NULL)
        return *buffer;  /* Found the newline */

    /* Need to allocate more memory */
    bufSize += bufsize;
    *buffer = realloc(*buffer, bufSize);

    /* Set the pointer to next position to read into */
    readpos = *buffer + strlen(buffer);

    /* Loop takes case of trying again */
}

注: 上記のコードはブラウザーで作成されたものであり、テストされていないため、適切に機能させるには調整が必要になる場合があります。

于 2013-02-01T07:53:02.987 に答える
1

reallocは、最初のパラメーターとして再割り当てが必要なバッファーを想定しています。

realloc(*buffer, buffSiz);
于 2013-02-01T07:54:03.300 に答える