#Reading a file and adding it as a string in a struct

51 messages · Page 1 of 1 (latest)

solar quarry
#

Hello everyone, I hope you're having a fantastic day!

I'm having a problem with adding one line of a file as a string in a struct. The struct kind of works like a list.

We have a .txt file that has names (that can have spaces!), so we need the whole line to be a string.
The next line will have two numbers that we need to keep in two ints (that part is working as it should.).
And it just repeats 9 times in the file.

I'm using a fscanf with "%[^\n]" to read the whole line, and when I print that string it gives me what it should.
But when I use my function to print the name of the struct as well as other variables, the name is always wrong.

Here's my code as well as screenshots to help:

struct ListResto* readRestos(char* nameFile) {
    // OPENING THE FILE
    FILE *p1;
    p1 = fopen(nameFile, "r");
    if (p1 == NULL) {
        printf("Error in opening file.\n");
        return NULL;
    }

    // CREATING THE STRUCT AND VARIABLES
    struct ListResto* l = createEmptyList();
    struct Resto* temp = NULL;

    char name[30];

    int check = 0;
    int lines = 0;

    while (check != EOF) {
        if (lines % 2 == 0) { // Used to see if we're at a line with text or other variables.
            fscanf(p1, "%[^\n]", name);
            printf("Name: %s\n", name);
            lines++;
            nameResto = name;
        } else {
            // I got rid of other variables for visibility.
            temp = createResto(name, quality, distance);
            addFirst(l, temp);
            lines++;
        }
        check = fgetc(p1);
    }
    fclose(p1);
    return l;
}


struct Resto* createResto(char* name) {
    struct Resto* r = malloc(sizeof(struct Resto));

    r->name = name;
    // I got rid of other variables for visibility.

    return r;
}

I'm pretty sure the thing to print a "Resto" struct is working considering that I just had to modify few things from another code.

Thanks for reading, wishing you a fantastic day!

gleaming crystalBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

solar quarry
#

(To clarify the screenshot:
"Quality" and "Distance" are just the int variables that are working as it should.
The "Name" (Nom) thing isn't working though, as they should be equal to text, and here the only few first letters appear before showing a weird thing.)

young sinew
#

I'm presuming that the printf("Name: %s\n", name) is not the sime line that's printing out the Nom : [garbage] in your screenshot?

solar quarry
#

Yeah indeed, sorry for the confusion.

young sinew
#

I'm p sure what's happening is you call fscanf to read into this name array, and when you call createResto you pass a pointer to the start of this array, and then r->name gets set to this pointer

but, your name array is on the stack! so when readRestos returns, r->name now points to invalid memory

solar quarry
#

The printf(Name: %s\n, Name) Was just to test it out, and it's working as it should.

But the Nom: garbage thing is a print function in the struct.

#

Ohhh, I completely forgot about that yeah, I didn't do a malloc for the string-...

young sinew
#

So you need to either store a char[30] in your struct Resto and copy name in in createResto, or allocate another buffer inside createResto

rugged heath
solar quarry
young sinew
#

just make sure to free it when you destroy your struct Resto :o

solar quarry
solar quarry
rugged heath
solar quarry
#

I will, thanks a lot for your kindness you all! (:

gleaming crystalBOT
#

@solar quarry Has your question been resolved? If so, run !solved :)

solar quarry
#

Okay, so I just added a r->name = malloc(sizeof(char[30])) in my struct and it did the exact same thing...

One thing that might be worth noting also is that if I try to create a struct with a string I give as an input, it works perfectly fine. It just doesn't when I'm reading the file...

#

Though if that can help somehow, the struct Resto is defined like that:

struct Resto {
    char* name;
    unsigned int quality;
    unsigned int distance;
    unsigned int time;
};

So perhaps it's waiting for a char*, but it receives a char[30] so it just doesn't work...?

rugged heath
#

they're the same type

solar quarry
#

Hm, weird then...

rugged heath
#

where do Quality & Distance come from

young sinew
#

can you post your revised createResto?

solar quarry
solar quarry
# young sinew can you post your revised `createResto`?

Sure, here it is!

struct Resto* createResto(char* name, unsigned int quality, unsigned int distance) {
    struct Resto* r = malloc(sizeof(struct Resto));
    r->name = malloc(sizeof(char[30]));
    r->name = name;
    r->quality = quality;
    r->distance = distance;
    r->time = 999;

    return r;
}
young sinew
#

yes, the same thing is happening because even though you're allocating some extra memory, you immediately lose the pointer

rugged heath
#

so quality & distance are effectively changed, but not name ?

young sinew
#

you need to copy the contents of name into r->name (after the allocation)

#

so strncpy(r->name, name, 29) e.g.

solar quarry
solar quarry
young sinew
#

well not necessarily strcpy, you just need to do anything that copies the data into r->name

#

in practice this means you probably want to call strncpy

rugged heath
#

I'm not sure about that r->name malloc, i'd go with malloc(30 + 1 * sizeof(char)

solar quarry
#

Oh my gosh the strcpy worked.

young sinew
#

sizeof(char) is defined to always be 1 by the standard, so there's no need

rugged heath
#

yeah ofc

young sinew
#

and generally sizeof(char) is considered bad practice

rugged heath
#

just clarity

#

well, it's ok to write that because of calloc typology

solar quarry
rugged heath
#

a char is 1 byte

solar quarry
young sinew
#

yeah fair

#

sizeof(char[30]) is fine

rugged heath
#

is that the same thing as = malloc (31) ? I've never seen that done

solar quarry
#

May I close the thread by marking it as solved then...?

young sinew
#

sizeof(char[30]) == 30, so it's the same as malloc(30)

#

yep if it works, go for it

solar quarry
#

Perfect, thanks to all of you for the help then! 💜
Wishing you all a fantastic day!

#

!solved