我试图将一些文本放入结构中,我的数组的一部分是一个包含文本一部分的数组。
例如我的结构是:
struct animal
{
char animal_Type[11];
int age;
int numberOfLegs;
int walksPerDay;
char favoriteFood[];
};
然后我将输入如下内容:
dog,2,4,2,biscuits,wet
cat,5,4,0,biscuits,wet,dry,whiskers
bird,1,2,0,birdseed,biscuits,bread,oats,worms,insects,crackers
我有一个可行的解决方案,可以将每天步行的所有值放入结构中,但是我希望能够将食物放入“最喜欢的食物”中。我有一个动态数组,但我不确定如何将剩余文本读入 favoriteFood 数组。
使用的代码是:
fp = open("animals.txt","r");
struct animal *animal = malloc(sizeof(sturct animal)*3);
int i = 0;
if(fp != NULL) {
while(i < 3) {
fscanf(fp,"%s %d %d %d %s",
animal[i].animal_Type,
animal[i].age,
animal[i].numberOfLegs,
animal[i].walksPerDay,
animal[i].favoriteFood); // need to be able to enter the string of food into here
i++
}
我该如何去做呢?
最佳答案
首先,您的struct
与您在评论中所说的不匹配。
char favoriteFood[];
上面是一个 char
数组,因此不可能包含最喜欢的食物列表,除非它是一个字符串。由于数组的大小未指定,因此您也无法像以前那样填充它。相反,你真正想要的是
char **favoriteFood;
unsigned int favoriteFoodSize;
这将让您创建一个扩展的字符串列表,以适应您需要容纳的任何数据。
至于读入,最好的方法是使用fgets
读取整行,然后使用strtok
之类的东西通过分隔符将行分开特点。首先定义一个非常大的字符串来保存整行,并定义一个 char *
来保存每个字段。
char buffer[1024];
char *token;
然后主循环将是这样的:
while(fgets(buffer,1024,fp)) {
token=strtok(buffer,",");
strcpy(beasts[i].animal_Type,token);
token=strtok(NULL,",");
beasts[i].age = atoi(token);
/* etc... */
}
您需要检查token
是否为NULL
以应对短行的可能性并进行相应的处理。并且还要确保复制到 animal_Type
中的字符串不超过 10 个字符...或者将其设为 char *
,这样您就可以拥有任意大小的字符串。
对于favoriteFood
,您需要使用realloc
来增加它的大小以容纳添加的每个新食物,并继续遍历字符串直到用完 token 。
token=strtok(NULL,",");
if(token) {
beasts[i].favoriteFood=malloc(sizeof(char *));
beasts[i].favoriteFood[0]=strdup(token); // Need to index using 0 as favoriteFoodSize won't have a value yet
beasts[i].favoriteFoodSize=1;
token=strtok(NULL,",");
while(token) {
beasts[i].favoriteFood=realloc(beasts[i].favoriteFood,(beasts[i].favoriteFoodSize+1)*sizeof(char *));
beasts[i].favoriteFood[beasts[i].favoriteFoodSize]=strdup(token);
beasts[i].favoriteFoodSize++;
token=strtok(NULL,",");
}
}
最后一个食物将有一个 \n
,因为 fgets
将其保存在它读取的缓冲区中,因此您可以使用它来判断您是否已完成处理所有食物(您还需要将其从最后的食物中取出)。或者,如果您没有它,您知道该行更长,您需要阅读更多内容。但根据您的示例数据,这似乎不太可能。
由于您正在进行大量内存分配,因此您应该确保检查返回的值以确保没有耗尽内存。
关于c - 动态 fscanf 到数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53710443/