Search code examples
carraysfilestructallocation

How to get int and string from file and save it in structure?


Let's assume that we have file which contains:

 1 John 
 2 Alex 
 3 Michael 

We can get one line using fscanf() function, but how to save it to below structure:

 typedef struct entry { 
 int n; 
 char *name; 
 } entry_t; 

I want to create the array of structures and save values from file to it, and do it dynamically. I've tried doing this in that way

entry_t *prt = malloc ( size * sizof(entry_t) ); 
//opening file 
prt[0].name = malloc ( sizeof("John") ); 
fscanf (fp,"%d %s", prt[0].n, prt[0].name); 

Ok, it works, but how to allocate memory for every name before get it from text file? I decided to use array of structures, because I'll use it to implement hash table.


Solution

  • sizeof("John") works fine for a string literal, but the names in the file are not known prior, so size must be determined dynamically.


    1. Use fgets() to read a line.

    2. Use sscanf(), strtol(), strtok() to parse that line.

    Example:

    int read_entry(FILE *istream, struct entry *record) {
      char buf[200];
      if (fgets(buf, sizeof buf, istream) == NULL) return -1;  // EOF
      buf[strcspn(buf, "\n")] = 0;  // lop off potential trailing \n
    
      int start;
      int end = 0;
      sscanf(buf, "%d %n%*s%n", &record->n, &start, &end); 
    
      if (end == 0) {
        return 0;  // failed to parse
      }
      record->name = strdup(&buf[start]);
      return 1; // Success
    } 
    

    Usage

    struct entry record;
    while (read_entry(stdin, &record) == 1) {
      printf("%d '%s'\n", record.n, record.name);
      ...
      // when done with the record,
      free(record.name);
    }
    

    strdup() is a common way to "duplicate" a string, yet it is not part of the standard C library. Easy enough to code: Example implementation