0

I'm trying to fill a table with structs inside a for loop, and I can't find anywhere how it's supposed to be done. Here is the code for the struct :

#define LEN 255

typedef struct {
    int number;
    char surname[LEN];
    char name[LEN];
} entry;

And how I'm attempting to read them from a file :

#include <string.h>
#define MAX_TAB 400

int read_entries (FILE* f, entry table[MAX_TAB]) {
    int i, number;
    char name[LEN], surname[LEN];

    for (i = 0 ; i < MAX_TAB ; i ++) {
        if (fscanf(f, "%d %s %s\n", &number, surname, name) != 3) {
            break;
        }
        table[i] = {number = number, surname = surname, name = name};
    }

    return i;
}

Unfortunately this doesn't work, as it seems struct initialisers are only available at variable declaration in C89. Then how do I use the values I just read to fill the table ? If possible, I would like answers that do not use malloc.


Here is a test file for convenience :

0 Liddell Alice
1 Sponge Bob
2 DaSilva Carlos
3 AndGoliath David
4 Eden Eve
5 Mirror Faith
6 Divine Grace
ice-wind
  • 690
  • 4
  • 20
  • 1
    Look at line `fscanf(f, "%d %s %s\n", &number, surname, name)`. Where does `surname` and `name` point to? – Jabberwocky Dec 01 '22 at 09:48
  • 1
    The `scanf` family of functions doesn't allocate memory for your strings. You must make sure that all strings a properly allocated, with a suitable size, and only pass valid and initialized pointers to `scanf`. – Some programmer dude Dec 01 '22 at 09:48
  • 2
    As for the initialization problem, just use plain assignments of each structure member. Like `table[i].number = number;` – Some programmer dude Dec 01 '22 at 09:49
  • `fscanf(f, "%d %s %s", & table[i].number, table[i].surname, table[i].name);` after making sure `name` and `surname` have been allocated – AR7CORE Dec 01 '22 at 09:53

1 Answers1

1

fscanf(f, "%d %s %s\n", &number, surname, name)

You can't store data "inside" uninitialized pointers, that's not how pointers work. See Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer


table[i] = {number = number, surname = *surname, name = *name};

C89 doesn't have any convenient way to do this using an initializer list. You'll have to use assignment etc:

char surname[100];
fscanf(..., surname, ...);

table[i].number = number;
table[i].surname = strdup(surname);
...

(strdup is as of the time I'm writing this widely available but not yet standard C. It will however get added in the upcoming C23 revision of the language.)

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • I will correct the pointers in the question, as I think it makes the answer harder to understand for future reference ! Thank you. – ice-wind Dec 01 '22 at 16:13