c - 动态 fscanf 到数组中

标签 c file input scanf

我试图将一些文本放入结构中,我的数组的一部分是一个包含文本一部分的数组。

例如我的结构是:

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/

相关文章:

c - 有没有办法查看 ctype.h 中的类型中有哪些字符?

c - 针对特定场景最好的Linux内核锁定机制是什么

file - NetLogo:输出文件中的换行符??没那么简单。

ruby - 寻找在 Ruby 中轻松实现类文件/IO 类的方法

java - 如何使用keyboard.next().charAt(0)将值存储到数组?在java中

jquery - .val() 不抓取输入到输入中的值

c - 从遗留 C 代码生成状态图

file - 如何将内存流加载到 LibVLC 中?

html - 更改/样式化 HTML 中的单个输入元素

c - C 中的无限循环