c - Easiest way to read this line of text into a struct? -


i have text file data in form:

lee aus 2 103 2 62 true check aus 4 48 0 23 false mills aus 8 236 0 69 false 

i need each line struct like, i'd avoid using fixed length arrays (the problem fgets far can tell):

struct data {     char *sname;     char *country;     int *a;     int *b;     int *c;     int *d;     char *hsisno; }; 

i new c. should use fscanf, or fgets?

fscanf stands "file scan formatted" , user data unformatted can get.

you should never use naked "%s" format strings on data don't have absolute control on can read.

the best solution use fgets read line since allows prevent buffer overflow.

then, once know size of line, that's maximum size of each string require. use sscanf heart's content actual fields.

one final thing. it's bit wasteful having int* types integers, since know have specific maximum size already. i'd use non-pointer variant, like:

struct data {     char *sname; char *country;     int a; int b; int c; int d;     char *hsisno; }; 

by way of example, here's safe code:

#include <stdio.h> #include <string.h>  // here's stuff linked list of nodes.  typedef struct sdata {     char *sname; char *country; char *hsisno;     int a; int b; int c; int d;     struct sdata *next; } data; data *first = null; data *last = null;  #define maxsz 100 int main (void) {     char line[maxsz], sname[maxsz], country[maxsz], hsisno[maxsz];     int a, b, c, d;     file *fin;     data *node;      // open input file.      fin = fopen ("file.in", "r");     if (fin == null) {         printf ("cannot open file\n");         return 1;     }      // process every line.      while (fgets (line, sizeof(line), fin) != null) {         // check line various problems (too short, long).          if (line[0] == '\0') {             printf ("line short\n");             return 1;         }          if (line[strlen (line)-1] != '\n') {             printf ("line starting '%s' long\n", line);             return 1;         }          line[strlen (line)-1] = '\0';          // scan individual fields.          if (sscanf (line, "%s %s %d %d %d %d %s",             sname, country, &a, &b, &c, &d, hsisno) != 7)         {             printf ("line '%s' didn't scan properly\n", line);             return 1;         }          // allocate new node hold data.          node = malloc (sizeof (data));         if (node == null) {             printf ("ran out of memory\n");             return 1;         }          node->sname = strdup (sname);         node->country = strdup (country);         node->a = a;         node->b = b;         node->c = c;         node->d = d;         node->hsisno = strdup (hsisno);         node->next = null;         if (first != null) {             last->next = node;             last = node;         } else {             first = node;             last = node;         }     }      fclose (fin);      // output list debugging.      node = first;     while (node != null) {         printf ("'%s' '%s' %d %d %d %d '%s'\n",             node->sname, node->country, node->a, node->b,             node->c, node->d, node->hsisno);         node = node->next;     }      return 0; } 

which reads in file , stores in linked list. outputs:

'lee' 'aus' 2 103 2 62 'true' 'check' 'aus' 4 48 0 23 'false' 'mills' 'aus' 8 236 0 69 'false' 

at end, expected.


i've done whole series of answers on pitfalls of using *scanf functions on non-controlled data (enter user:14860 fgets search box above), of (here, here , here, example) include perennial favourite function of mine, getline, safer user input.


Comments

Popular posts from this blog

ASP.NET/SQL find the element ID and update database -

jquery - appear modal windows bottom -

c++ - Compiling static TagLib 1.6.3 libraries for Windows -