简体   繁体   中英

Repeating strings but not ints when reading from files

I've written a function that uses fscanf("%s &d &d &d") to read from a file. For some reason, when I display the output, all the integer values are correct, but the strings are all the same. food_stuff is a struct held in an array.

*EDIT I've tried using a for to add each element from one array to the other, and I've tried strcpy .

Here's the function.

int readFromFile()
{
    char*name;
    int type;
    int cals;
    int price;

    FILE * food_file;
    food_file = fopen ("food_file.txt", "r");
    while(fscanf(food_file, "%s %d %d %d", name, &type, &cals, &price)!=EOF)
    {
        food_stuff fs;
        fs.name = name;
        fs.type = type;
        fs.calories = cals;
        fs.price = price;
        fflush(stdin);
        addItem(fs);
    }

}

As a commenter already has pointed out, you need to allocate memory for your variable name . Because the variable is temporary, you could just declare a local char array on the stack instead of allocationg memory on the heap:

char name[40];

Your problem is that the name field in your structure is probably also only a pointer to char. That pointer points to name for all footstuff structs you generate, which is the same for all instances, only with different contents. (What's worse: That buffer won't exist any more if you leave readFromFile , invalidating the name field for every foodstuff.)

One possible solution is to make the name field also a buffer, eg:

typedef struct food_stuff food_stuff;

struct food_stuff {
    char name[40];
    int type;
    int cals;
    int price;
};

When you assign the read data to the struct, don't copy the pointer, but copy the contents with strcpy . (You need to include <string.h> for that):

strcpy(fs.name, name);

This solution assumes that all names are less than 39 characters long, which is not a safe assumption for real data. You should specify a width on the %s format in your call to fscanf .

Another solution is leave the struct definition as I assume it is now with char *name and to allocate memory for each new struct. You still have to copy the contents, though:

fs.name = malloc(strlen(name) + 1);
// error check omitted
strcpy(fs.name, name);

This solution requires that you free the extra memory allocated when you free the foodstuff structs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM