【发布时间】:2018-04-20 15:54:14
【问题描述】:
我想要做的是获取一个文本文件并将 4 行存储到我的结构中,使用带有 fgets 和 sscanf 的循环来检索数据。
结构是这样的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 16
#define N 4
struct Prova
{
char nome[SIZE];
int num;
};
现在我的函数看起来像这样:
void get_str(struct Prova * ptr){
FILE *f;
int i = 0;
if(!(f = fopen(PATH,"r+")))
{
perror("Errore in apertura");
exit(0);
}
void * buffer = malloc(sizeof(struct Prova ));
while(fgets(buffer,sizeof(struct Prova), f))
{
if(sscanf(buffer, "%s %d", (ptr+i)->nome, &(ptr+i)->num) > 0)
{i++;}
}
free(buffer);
fclose(f);
}
更新:现在该功能可以工作了,谢谢大家。
主要功能是这样的:
int main()
{
struct Prova * ptr = malloc(N*sizeof(struct Prova));
get_str(ptr);
for(int i = 0; i< N; i++)
{
printf("\n%s %d", (ptr+i)->nome, (ptr+i)->num);
}
return 0;
}
我要读取的文本文件是这样的:
Pippo 4
Paperino 1
Topolino 3
Zio_paperone 2
【问题讨论】:
-
您确定
Paperino和1之间以及Topolino和3之间的字符是实际上 空格(代码0x20)而不是不间断空格(代码 0xa0)?在大多数文本编辑器中,它们看起来都一样,您无法分辨出区别 -
fgets(buffer,sizeof(struct Prova), f)不是很正确,因为你真的想要[at most SIZE - 1 characters][space][1 digit][maybe a newline],而不是[at most SIZE - 1 characters][space][sizeof(int) digits],这甚至没有考虑填充等的可能性。在实践中它可能“足够接近”但是在语义上似乎不合适。 -
还需要查看
sscanf的返回值。你没有,这就是打印最后一个0的原因 -
@underscore_d "[at most SIZE - 1 characters][space][1 digit]" 也需要
'\n'和'\0'的空间。 OTOH 只需使用 2 倍预期大小的缓冲区。缓冲区稍大一点也不成问题。 -
@chux 好点:已编辑。是的,在这种情况下,稍微过度分配也很有意义——如果不是更多的话,因为这样可以减少意外过长的行导致任何爆炸的风险。但是,代码反而暗示它试图非常具体地确定大小,但使用了错误的基础;这是我的抱怨。
标签: c pointers data-structures