是否将.dat数据添加到C结构?
所以我必须在C语言中快速完成一件事,需要一些指导,因为我通常不使用C语言 我有City.dat文件,其中包含一些数据(我简化了它): 在City.h文件中,我为其创建了结构:是否将.dat数据添加到C结构?,c,file-io,C,File Io,所以我必须在C语言中快速完成一件事,需要一些指导,因为我通常不使用C语言 我有City.dat文件,其中包含一些数据(我简化了它): 在City.h文件中,我为其创建了结构: typedef struct{ int postalCode; char cityName; } City; typedef struct { City **city; } CityList; 我应该如何在City.c中进行迭代以从City.dat收集所有数据?显然,我需要一个for循环,但
typedef struct{
int postalCode;
char cityName;
} City;
typedef struct {
City **city;
} CityList;
我应该如何在City.c中进行迭代以从City.dat收集所有数据?显然,我需要一个for循环,但我想看一个示例,如何从dat文件读取数据并打印出收集的城市
char cityName;
真的应该
char *cityName;
我们实际上可以在这里使用灵活的数组,但我们不会,因为您的实际结构可能有多个字符串
收集循环很容易
#define SPLIT 15
// Stupid helper function to read a single line no matter how long.
// Really should be in the standard library but isn't.
static int readline(FILE *h, char **buf, size_t *nbuf)
{
if (!*buf) {
*buf = malloc(128);
nbuf = 128;
}
size_t offset = 0;
do {
if (offset + 1 >= *nbuf) {
// Just keep growing the line buffer until we have enough room.
size_t nbuf2 = *nbuf << 1;
char *buf2 = realloc(*buf, nbuf2);
if (!buf2) return -1;
*buf = buf2;
*nbuf = nbuf2;
}
if (!fgets(buf + offset, *nbuf - offset, h)) return -1;
offset += strlen(buf + offset);
} while (offset > 0 && buf[offset - 1] == '\n');
return 0;
}
CityList readfile(const char *file);
{
errno = 0; // Check errno for short read.
FILE *f = fopen(file);
if (!f) return NULL;
char *buf = NULL;
size_t nbuf = 0;
City **cities = NULL;
size_t ncities;
size_t acities;
if (readline(f, &buf, &nbuf)) return NULL; // get rid of header line
acities = 4;
ncities = 0;
cities = malloc(acities * sizeof(City**));
if (!cities) return NULL;
cities[0] = NULL; // Mark list empty
while (!readline(f, &buf, &nbuf)) {
// get new city struct
int n = strtol(buf);
int len = strlen(buf);
if (len > 0 && buf[len] == '\n') buf[len--] = 0; // Cut off trailing \n
if (len + 1 > SPLIT) /* validity check */ {
if (ncities + 1 == acities) {
size_t ncities2 = ncities << 1;
City **cities2 = realloc(ncities 2 * sizeof (City**));
if (!cities2) break;
}
// Allocate the entire struct and its data all at once.
char *citybuf = malloc(sizeof(City*) + sizeof(City) + len - SPLIT + 1);
City **city = (City*)citybuf;
// Slot all the stuff into the structure
city[0] = citybuf + sizeof(City *);
city[0]->postalCode = n; // Value saved from above.
city[0]->cityName = citybuf + sizeof(City *) + sizeof(City);
strcpy(city[0]->cityName, buf + SPLIT);
// Add city to list
cities[ncities] = city;
cities[++ncities] = NULL; // Mark end of list
}
}
free(buf);
fclose(f);
CityList l = { cities };
return l
}
#定义拆分15
//愚蠢的助手函数读取一行无论多长。
//确实应该在标准库中,但不是。
静态整型读取行(文件*h,字符**buf,大小*nbuf)
{
如果(!*buf){
*buf=malloc(128);
nbuf=128;
}
尺寸偏差=0;
做{
如果(偏移量+1>=*nbuf){
//继续增加缓冲区直到我们有足够的空间。
大小nbuf2=*nbuf0&&buf[offset-1]='\n');
返回0;
}
城市列表读取文件(常量字符*文件);
{
errno=0;//检查errno是否为短读。
文件*f=fopen(文件);
如果(!f)返回NULL;
char*buf=NULL;
尺寸_t nbuf=0;
城市**城市=空;
大小不一致;
面积;;
if(readline(f,&buf,&nbuf))返回NULL;//去掉头行
人口=4;
ncities=0;
城市=malloc(城市*sizeof(城市**));
如果(!cities)返回空值;
城市[0]=NULL;//标记列表为空
while(!readline(f,&buf,&nbuf)){
//获得新的城市结构
int n=标准温度(buf);
int len=strlen(buf);
如果(len>0&&buf[len]='\n')buf[len-->=0;//切断尾随\n
如果(len+1>拆分)/*有效性检查*/{
如果(ncities+1==acities){
size\u t ncities2=ncities postalCode=n;//从上面保存的值。
城市[0]->cityName=citybuf+sizeof(城市*)+sizeof(城市);
strcpy(城市[0]->cityName,buf+SPLIT);
//将城市添加到列表中
城市[城市]=城市;
城市[++ncities]=NULL;//标记列表末尾
}
}
免费(buf);
fclose(f);
城市列表l={cities};
返回l
}
当您释放此项时,CityList中的每个条目都需要释放,直到您到达终止的NULL
。分配同时分配了子指针、结构和结构内容,因此每个城市只有一个free
调用
特别值得注意的是:缓冲区在早期被分解成块。然后城市结构被一次分配,因为我们可以查看结构元素并说出我们需要多少空间。如果记录本身在读入后没有被编辑,这是惯用的方法,因为代码既短又快。我很恼火d试图找出如何处理错误,只是说readerrno
确实有效,但有些人不喜欢清除errno
的代码。在快乐的道路上,清除errno
是可以的。只有在错误路径上,它才会导致问题
我没有运行这段代码。它可能有bug。你的问题太广泛了。如果你不知道如何从C语言的文件中读取,你应该从一个教程开始:如果这个文件有什么特别的地方给你带来麻烦,你应该指定它。如果你希望这个网站上有人编写整个作业e对你来说,你在错误的网站上。祝你好运!@LevM:我决定把这个当作不是家庭作业。虽然我真的不知道,但他说问题已经解决了,所以他无法复制/粘贴任何答案。然后我给出了完整流畅的答案。如果这个问题在家庭作业中被删除,它会像拇指酸痛一样突出。这正是我作为sta所寻找的导游,谢谢!
#define SPLIT 15
// Stupid helper function to read a single line no matter how long.
// Really should be in the standard library but isn't.
static int readline(FILE *h, char **buf, size_t *nbuf)
{
if (!*buf) {
*buf = malloc(128);
nbuf = 128;
}
size_t offset = 0;
do {
if (offset + 1 >= *nbuf) {
// Just keep growing the line buffer until we have enough room.
size_t nbuf2 = *nbuf << 1;
char *buf2 = realloc(*buf, nbuf2);
if (!buf2) return -1;
*buf = buf2;
*nbuf = nbuf2;
}
if (!fgets(buf + offset, *nbuf - offset, h)) return -1;
offset += strlen(buf + offset);
} while (offset > 0 && buf[offset - 1] == '\n');
return 0;
}
CityList readfile(const char *file);
{
errno = 0; // Check errno for short read.
FILE *f = fopen(file);
if (!f) return NULL;
char *buf = NULL;
size_t nbuf = 0;
City **cities = NULL;
size_t ncities;
size_t acities;
if (readline(f, &buf, &nbuf)) return NULL; // get rid of header line
acities = 4;
ncities = 0;
cities = malloc(acities * sizeof(City**));
if (!cities) return NULL;
cities[0] = NULL; // Mark list empty
while (!readline(f, &buf, &nbuf)) {
// get new city struct
int n = strtol(buf);
int len = strlen(buf);
if (len > 0 && buf[len] == '\n') buf[len--] = 0; // Cut off trailing \n
if (len + 1 > SPLIT) /* validity check */ {
if (ncities + 1 == acities) {
size_t ncities2 = ncities << 1;
City **cities2 = realloc(ncities 2 * sizeof (City**));
if (!cities2) break;
}
// Allocate the entire struct and its data all at once.
char *citybuf = malloc(sizeof(City*) + sizeof(City) + len - SPLIT + 1);
City **city = (City*)citybuf;
// Slot all the stuff into the structure
city[0] = citybuf + sizeof(City *);
city[0]->postalCode = n; // Value saved from above.
city[0]->cityName = citybuf + sizeof(City *) + sizeof(City);
strcpy(city[0]->cityName, buf + SPLIT);
// Add city to list
cities[ncities] = city;
cities[++ncities] = NULL; // Mark end of list
}
}
free(buf);
fclose(f);
CityList l = { cities };
return l
}