0

こんにちは、データを構造体の配列に読み込むという質問があります。これは私がこれまでに持っているものです:

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

#define MAX_NAME   20
#define FILE_NAME  50
#define LIST_SIZE 50
//void getData(RECORD name[], RECORD score)


typedef struct 
{
    char *name;
    int  score;
}RECORD;


int main (void)
{
    // Declarations
       FILE *fp;
       char fileName[FILE_NAME];
       RECORD list[LIST_SIZE];
       char buffer[50];
       int count = 0;
    // Statements
       printf("Enter the file name: ");
       gets(fileName);

       fp = fopen(fileName, "r");

       if(fp == NULL)
           printf("Error cannot open the file!\n");
       while (fgets(buffer, LIST_SIZE, fp) != NULL)
         {   
                     printf("%s\n", buffer);
         list[count].name = (char*) calloc(strlen(buffer), sizeof(char));
         sscanf(buffer,"%s%d", list[count].name, &list[count].score);
         printf("name is: %s and score is:%d \n", list[count].name, list[count].score);
         count++;

         }
       printf("Read in %d data records\n", count);
       return 0;
}

そのため、名前を割り当てずに印刷しようとするとwhileループ内で正常に動作するように見えますが、名前にメモリを割り当てた後、印刷時にバッファに最初の名前がありません。だから私はこの出力を持っています

Enter the file name: in.txt
Ada Lovelace, 66

Torvalds, 75

Norton, 82

Thompson, 82

Wozniak, 79

Andreessen, 60

Knuth, 60

Goldberg, 71

Hopper, 82

Joy, 91

Tanenbaum, 71

Kernighan, 72
Read in 12 data records

正しい出力の代わりに

Enter the file name: in.txt
Ada Lovelace, 66

Linus Torvalds, 75

Peter Norton, 82

Ken Thompson, 82

Steve Wozniak, 79

Marc Andreessen, 60

Donald Knuth, 60

Adele Goldberg, 71

Grace Hopper, 82

Bill Joy, 91

Andrew Tanenbaum, 71

Brian Kernighan, 72
Read in 12 data records

これはfscanfの行をコメントアウトした後の出力なので、そこにエラーが発生しているのではないかと思います。

fscanfステートメントを修正しました

Enter the file name: in.txt
Ada Lovelace, 66

name is: Ada and score is:3929744
Linus Torvalds, 75

name is: Linus and score is:3929752
Peter Norton, 82

name is: Peter and score is:3929760
Ken Thompson, 82

name is: Ken and score is:3929768
Steve Wozniak, 79

name is: Steve and score is:3929776
Marc Andreessen, 60

name is: Marc and score is:3929784
Donald Knuth, 60

name is: Donald and score is:3929792
Adele Goldberg, 71

name is: Adele and score is:3929800
Grace Hopper, 82

name is: Grace and score is:3929808
Bill Joy, 91

name is: Bill and score is:3929816
Andrew Tanenbaum, 71

name is: Andrew and score is:3929824
Brian Kernighan, 72
name is: Brian and score is:3929832
Read in 12 data records

ご覧のとおり、行名は次のとおりです。名前のみを出力し、姓と整数スコアのアドレスは出力しません。

4

3 に答える 3

2

fgets と fscanf は、どちらもファイルから読み取っているため、互いに競合しています。fgets を使用してファイルからバッファーに読み取り、sscanf を使用してデータを構造体に解析します。

一般に、fscanf よりも fgets の方が安全であるため、fgets を使用することをお勧めします。いずれにせよ、fgets と fscanf を混在させないでください。

于 2013-04-13T19:42:50.127 に答える
0

コードにはいくつかの問題があります。入力ファイルに特定のパターンがある場合は、まず scanf と fscanf を使用してみてください。fgets と gets を使用するときに、改行文字に問題がありました。また、fscanf は、スペース文字または改行が見つかるまで読み取ります (コードでこれを考慮しましたか? 名前セグメントの 1 つだけを読み取る理由は非常に明白であるため)。同じ問題で printf を使用している可能性があります。\n または ' ' までしか書き込みません。C++ を使用できる場合は、ifstream と sstream の使用を検討してください。

于 2013-04-13T19:59:59.077 に答える
0

これを試してください:

...

while (fgets(buffer, LIST_SIZE, fp) != NULL)
{
    char *tok;
    printf("%s\n", buffer);

    tok = strchr(buffer, ',');
    if (!tok)
    {
        printf("Bad line\n");
        continue;
    }

    list[count].name = strndup(buffer, tok - buffer);
    list[count].score = atoi(tok + 1);

    printf("name is: %s and score is:%d \n", list[count].name, list[count].score);
    count++;
}
...
于 2013-04-13T21:49:27.400 に答える