c - 如何将文件中的数据加载到链表c中
问题描述
程序应该读取一个简单的文本文件并将数据(名称和 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;
}
现在输出是这样的:
解决方案
由于传递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
and p.id
。
推荐阅读
- python-3.x - 我想从列表中选择一个元素,该元素充当字典中的键,其值为最小值。如何做到这一点(见下文)?
- c++ - void 是什么意思,或者在这种情况下它如何影响 T?
- jquery - 将 jquery 文件链接到 html
- c++ - Serial read() 在与 BLDC 控制器通信时以 errno 11 终止
- ansible - 可以使用“sudo su -”更改用户
"(无密码)与 Ansible? - android - Android MediaRecorder 使用哪种编码器?
- python-2.7 - 从dict中移动N个键,每个都是元组列表到N维数组或其他结构中
- python - 在使用 conda 构建的包中包含环境
- javascript - 如何通过反应读取 cookie?
- apache-spark - 使用 Spark Streaming 更新基于 Kafka Stream 的静态源?