提问人:Akiyuu 提问时间:11/19/2022 更新时间:11/19/2022 访问量:39
C:新手使用 malloc 尝试文件读取和结构分配
C: Newbie attemping file reading and struct allocation using malloc
问:
我正在尝试将存储在 details.txt 文件中的值存储到动态分配的结构中的适当位置。我是否错误地做了一些事情(应该很简单)以使其不起作用?我是否有必要使用 strtok 并按“,”进行拆分?
我的详细信息.txt如下:
米奇,8,1.78,汉堡
Murray,42,6.5,千层面
特拉维斯,64,1.85,寿司
SAM,12,1.94,培根
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFERSIZE 256
typedef struct
{
char name[BUFFERSIZE];
int favnumber;
float height;
char favfood[BUFFERSIZE];
} Person;
void print_person(Person *p)
{
printf("name: %s\n", p->name);
printf("num: %d\nheight: %.2f\nfav. food: %s\n\n",
p->favnumber, p->height, p->favfood);
}
int count_lines(FILE *fp)
{
int nlines = 0;
char c;
for (c = fgetc(fp); c != EOF; c = fgetc(fp))
{
if (c == '\n')
{
nlines++;
}
}
rewind(fp);
return nlines;
}
int main(void)
{
FILE *fp = fopen("details.txt", "r");
// count lines
int nlines = count_lines(fp);
printf("found %d lines\n\n",nlines);
Person *people = (Person*)malloc(nlines*sizeof(Person));
char buffer[BUFFERSIZE];
int i = 0;
while (fgets(buffer,BUFFERSIZE,fp) != NULL)
{
sscanf(buffer,"%s%d%f%s",people[i].name,
&(people[i].favnumber),
&(people[i].height),people[i].favfood);
print_person(&(people[i]));
i++;
}
printf("found %d people\n",i);
free(people);
fclose(fp);
}
不幸的是,我的程序的当前输出是:
共找到 4 条线路
常用中文名:Mitch,8,1.78,Burgers
数量: 0
高度: 0.00
最喜欢的。食物:
...
找到 4 人
答:
2赞
Allan Wind
11/19/2022
#1
问题是首先解析整行,并且需要在格式字符串中分隔字段。这里还不是问题,但我也使用了 %[^,] 作为最后一个格式字符串,所以它不会停在第一个空格处。还增加了字符串的精度,以避免缓冲区溢出:%s
,
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFERSIZE 255
#define str(s) str2(s)
#define str2(s) #s
typedef struct
{
char name[BUFFERSIZE+1];
int favnumber;
float height;
char favfood[BUFFERSIZE+1];
} Person;
void print_person(Person *p)
{
printf("name: %s\n", p->name);
printf("num: %d\nheight: %.2f\nfav. food: %s\n\n",
p->favnumber, p->height, p->favfood);
}
int count_lines(FILE *fp)
{
int nlines = 0;
char c;
for (c = fgetc(fp); c != EOF; c = fgetc(fp))
{
if (c == '\n') {
nlines++;
}
}
rewind(fp);
return nlines;
}
int main(void)
{
FILE *fp = fopen("details.txt", "r");
// count lines
int nlines = count_lines(fp);
printf("found %d lines\n\n",nlines);
Person *people = (Person*)malloc(nlines*sizeof(Person));
char buffer[BUFFERSIZE+1];
int i = 0;
while (fgets(buffer,BUFFERSIZE+1,fp) != NULL)
{
// Changed line, see formatting of %s
sscanf(buffer,
"%" str(BUFFERSIZE) "[^,],%d,%f,%" str(BUFFERSSIZE) "[^,]",
people[i].name,
&(people[i].favnumber),
&(people[i].height),people[i].favfood);
print_person(&(people[i]));
i++;
}
printf("found %d people\n",i);
free(people);
fclose(fp);
}
评论
0赞
chux - Reinstate Monica
11/19/2022
哦 - 串联 - 不错。#
0赞
chux - Reinstate Monica
11/19/2022
也许是最后一次?"[^\n]"
0赞
Allan Wind
11/19/2022
@chux-ReinstateMonica 由于缓冲区的大小与两个字符串相同,我认为原始代码无论如何都不会超出缓冲区。 如果添加其他字段,可能会更符合未来需求(即在代码更新之前被忽略,其中“[^\n]”会将其读取为一个字段;顺便说一句,我首先考虑了您的建议。"[^,]"
2赞
chux - Reinstate Monica
11/19/2022
公平点。只是裸体等引起了人们的注意。%s
评论