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

char *readLine(FILE *inFile)  //Simply reads line in a text file till "\n"
{
    char *line = realloc(NULL, 1);
    char c;
    int i=0;
    while (!feof(inFile))
    {
        c = fgetc(inFile);
        if (ferror(inFile)) printf("Error reading");
        if (c == 10)
            {
                realloc(line,i+1);
                line[i]= 10;
                break;
            }
        realloc(line, i+1);
        line[i++] = c;
    }
    return line;
}

int main(int argc,char **argv)
{
    FILE *inFile;
    inFile = fopen("testFile","r");
    printf("%s",readLine(inFile));
    printf("%s",readLine(inFile));
    printf("%s",readLine(inFile));
    return 0;
}

testFileの内容が次の場合:-

abc
def
ghi

3つのprintfステートメントは「abc」を3回表示する必要があります。ただし、出力は次のとおりです。

abc
def
ghi

私はどこかの概念が間違っていることを知っています。plsは役立ちます。

4

3 に答える 3

6

の使用法realloc()が正しくありません。

realloc(line,i+1); // wrong

// OK
void *new_line = realloc(line,i+1);
if (!new_line)
{
    free(line);
    return NULL;
}
line = new_line;

line値で渡されるため、変更されません。実際に再割り当てされたメモリは戻り値にあります。したがってline、何度も同じままであり、同じ行が何度も表示されます。 編集:それはバグですが、繰り返し行を引き起こすものではないことに気づきました。他のポイントはまだ有効です。

何が悪いの:

  1. 毎回新しく再割り当てされたポインタを失うことにより、メモリリークが発生します。
  2. line古い値がヒープの別の部分に再割り当てされた場合、再割り当て後に無効になる可能性があるため、解放されたメモリにアクセスしている可能性があります。
  3. 文字ごとにメモリを再割り当てしているため、コストのかかる操作になる可能性があります。
于 2010-01-10T07:41:55.657 に答える
4

しかし、私はファイルポインタを値で渡しています。だから私は何度も何度も出力「abc」を取得する必要があります

ああ、私はあなたの混乱を理解しています。

ファイルポインタは、実際のファイル構造のみを指します。現在のオフセットなどの状態は、ポインターの一部ではなく、内部構造の一部です。

これについて考える別の方法は、ファイルを表す実際のオブジェクトがFILEであるということです。参照渡しのセマンティクスを取得するには、オブジェクトへのポインターを渡します。参照で通過しているので、各行は最後の行が中断したところから始まります。

于 2010-01-10T08:12:24.263 に答える
4

fgetc()ファイルポインタ(「次に読み取る文字が配置されている場所」)を進めます。これにより、ループで呼び出して、文字の行全体を読み取ることができます。

改行文字を超えて進むと、自然に次の文字に移動します。これは次の行の始まりです。

関数を使用してファイルポインタを変更できますfseek()。たとえば、呼び出すfseek(inFile, 0, SEEK_SET)とファイルの先頭にリセットされ、次のfgetc()呼び出しがファイルの最初の文字からやり直されます。

于 2010-01-10T07:48:48.357 に答える