-2

私はこの関数を書きました(以下)。ファイルを1行ずつ読み込む必要があります。行を編集し、特定の単語/文字をさまざまな機能に配置します。次に、関数は「entrant」構造体の配列(malloc)に入れられます。

問題は、ループを終了して配列を出力しようとすると、配列に配置された最後のstructname変数が出力される唯一のname変数になることです。たとえば、配列の最初の10個の構造体名変数を出力しようとすると、最後の構造体名変数が10回出力されます。ただし、整数(数値変数)は正常に機能します。

fgets()を使用してファイルの行を読み取り、ファイルの最後でループを解除します。おそらくfgets()が問題になる可能性がありますが、それはありそうもないようです...

問題が何であるかはわかりませんが、前述したように、数値変数は正常に出力されますが、名前は最後の変数のみを出力します。

しかし、ファイルから情報を取得することはできません。私のloopprintステートメントをwhileループの中に入れても、それでも機能しません。

注意すべき点の1つは、strtok、strcpy、およびstrcatを使用して行を個別の変数に入れることが正常に機能していることです。それが原因ではないと思います。

struct entrant {
  int number;
  char *name;
};


void read_in_entrants(char fileName[]) {
    FILE *fr;
    fr = fopen(fileName, "rt");

    //Init.
    struct entrant * entrant_array = (struct entrant*) malloc(sizeof (struct entrant));
    int j, temp, k = 0;
    int *number;
    char line[80];
    char name[80];
    char surname[80];

    while(1) {
        //Read line in file.
        fgets(line, 80, fr);

        //If at end of file break from loop.
         if (feof(fr)) break;

        //Edit line to be stored in variables.
        number = strtok(line, " ");
        strcpy(name, strtok(NULL, " "));
        strcpy(surname, strtok(NULL, " "));
        strcat(name, " ");
        strcat(name, surname);

        //Add variables to struct array.
        entrant_array[k].number = atoi(number);
        entrant_array[k].name = name;
        printf(" %d %s\n", entrant_array[k].number, entrant_array[k].name);

        //Handle malloc array memory.
        temp = realloc(entrant_array, (k + 2) * sizeof (struct entrant));
        if (temp != NULL) {
            entrant_array = temp;
        } else {
            free(entrant_array);
            printf("Error in memory allocation!");
            return 1;
        }
        //Increase k.
        k++;
    }

    //Print struct values in array.
    for (j = 0; j < 10; j++) {
        printf(" %d %s", entrant_array[j].number, entrant_array[j].name);
    }

   //Shut down.
   free(entrant_array);
   fclose(fr);
}

とにかく、私はこれに文字通り何時間も苦労していて、それを修正することはできません。私のCの知識は非常に限られており、これを修正するために何をする必要があるかについてはかなり迷っています。

助けてくれてありがとう、それは非常にありがたいです:)

4

1 に答える 1

4

entrant.nameは、同じローカル文字配列に割り当てているポインタです。したがって、すべてのポインターは同じ変数を指します。この変数には、最後に読んだものだけが含まれます。スコープ外になるまで、その時点でランダムメモリをポイントします。

最も簡単な修正は、交換することです

entrant_array[k].name = name;

entrant_array[k].name = strdup(name);

ただし、後でそのメモリを解放することを忘れないでください。

于 2012-12-07T20:51:35.337 に答える