程序应该读取一个简单的文本文件,并将数据(名称和ID)存储到链表中。
这是链表:
struct Prova
{
char nome[16];
int id;
};
typedef struct Node {
struct Prova struttura;
struct Node * next;
}TNodo;
typedef TNodo* Nodo;
此功能创建链接列表:
void NewList(struct Prova p, Nodo * pp)
{
Nodo temp;
temp = (Nodo)malloc(sizeof(struct Node));
temp->struttura = p;
temp->next = *pp;
*pp = temp;
}
这是我写的用来读取文件的函数:
void Load(Nodo *pp)
{
FILE *f;
struct Prova p;
char * buffer;
if(!(f = fopen(PATH, "r")))
{
perror("Error");
exit(-1);
}
buffer = malloc(sizeof(struct Prova));
while(fgets(buffer, sizeof(buffer), f))
{
if(sscanf(buffer, "%s%d", p.nome, &p.id) > 0)
{
NewList(p, pp);
}
}
free(buffer);
fclose(f);
}
我想读的文本文件是:
Stefano 31
Paperino 23
Pippo 1
Pluto 14
显示列表的功能如下:
void View(struct Prova p)
{
printf("%s %d\n", p.nome, p.id);
}
void ViewList(Nodo nodo)
{
while(nodo != NULL)
{
View(nodo->struttura);
nodo = nodo->next;
}
程序编译正常,但它以奇怪的顺序输出数据。 如果您需要更多信息,请告诉我,我认为这些都与最新的Load()函数有关。
主要功能是:
int main()
{
int scelta;
struct Prova test;
Nodo lista = NULL;
do {
scelta = Menu();
switch (scelta)
{
case 1: Load(&lista); break
case 2: ViewList(lista); break;
default: scelta = 0;
}
} while (scelta != 0);
return 0;
}
目前输出为:
答案 0 :(得分:1)
由于将sizeof(buffer)
传递给fgets()
,问题正在发生。 buffer
是指针,sizeof(buffer)
将根据基础架构4
位或8
位返回32
或64
。将其更改为:
while(fgets(buffer, sizeof(struct Prova), f))
,因为您要将sizeof(struct Prova)
尺寸分配给buffer
。
这也不是问题的正确解决方案。原因是 -
说,你的文件有这些数据:
abcdefghijklmno 123456789
名称部分15
字符长nome
成员可以容纳,id
成员也可以保留数字123456789
,因为它少于INT_MAX
。 fgets
从流中读取字符,上面给出的数据大小为25
个字符。在您的代码中,您将sizeof(struct Prova)
大小内存分配给buffer
,struct Prova
的大小为20
字节。因此,对于上面给出的数据,buffer
没有分配足够的内存来一次读取整行,因为fgets
读取直到size-1
字符被读取或者换行或者达到文件结尾,以先发生者为准。因此,在这种情况下,将读取部分行并将其传递给sscanf()
,并在下一次迭代中读取该行的其余部分并传递给sscanf()
,这将得到不正确的结果。
您不应根据buffer
的大小将内存分配到struct Prova
。相反,我建议采用更大尺寸的buffer
,如下所示(无需动态分配):
char buffer[100];
确保它应该足够大,以便在fgets
的一次读取中容纳文件的一行,或修改您的代码,以便在p.nome
之前填充p.id
和fgets
点击换行符或EOF即确保读取整行,然后只sscanf()
p.nome
和p.id
。