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 将数据解析到结构中。

一般来说,您应该更喜欢 fgets 而不是 fscanf,因为它更安全。无论如何,不​​要混合使用 fgets 和 fscanf。

于 2013-04-13T19:42:50.127 回答
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 回答
0

您的代码有几个问题。首先,如果您的输入文件中有特定模式,请尝试使用 scanf 和 fscanf。在使用 fgets 和 get 时,我遇到了换行符的问题。fscanf 也会读取直到找到空格字符或换行符(您是否在代码中考虑过这一点?因为很明显为什么它只读取一个名称段)。可能是您使用 printf 时遇到了同样的问题,它只写到 \n 或 ' '。如果您可以使用 C++,您可能想考虑使用 ifstream 和 sstream。

于 2013-04-13T19:59:59.077 回答