/* BEGIN file_parse.c */ /* From news:comp.lang.c > The general form of the file is > > 00000000 USNIST00Z 00000000_00 0 000 000 000 0000 000 > > I need to read the file line by line and eventually parse > out each piece of the file and store in arrays that correspond > to the specific line. array1[1] would be > the first entry in the first line and so on and so forth. */ #include "file_lib.h" #include "list_lib.h" #include "list_io.h" #include #include #include #define LINES_PER_FILE 3 #define LU_RAND_SEED 123456789LU #define LU_RAND(S) ((S) * 69069LU + 362437 & 0XFFFFFFFF) void free_ptrs(char ***p, size_t nmemb); void display_array(char ***p, size_t n_lines, size_t n_fields); int main(void) { size_t line, n_fields, field; int rc; char fn[L_tmpnam]; FILE *fp; char *ptr; char ***f; long unsigned lu_seed = LU_RAND_SEED; char *buff = NULL; size_t size = 0; size_t n_lines = 0; list_type *head = NULL; list_type *tail = NULL; puts("/* BEGIN file_parse.c output */"); /* ** Create input text file. ** Open temporary input text file for writing. */ tmpnam(fn); fp = fopen(fn, "w"); if (fp == NULL) { fputs("fopen(fn), \"w\") == NULL\n", stderr); exit(EXIT_FAILURE); } /* ** Write temporary input text file. */ for (line = 0; line != LINES_PER_FILE; ++line) { lu_seed = LU_RAND(lu_seed); fprintf(fp, "%.8lu %s %.1lu %.3lu %.3lu %.3lu %.4lu %.3lu\n", line, "USNIST00Z 00000000_00", lu_seed % 10, lu_seed % 1000, lu_seed % 500, lu_seed % 250, lu_seed % 10000, lu_seed % 125); } /* ** Close temporary input text file. */ fclose(fp); /* ** Open temporary input text file for reading. */ fp = fopen(fn, "r"); if (fp == NULL) { remove(fn); fputs("fopen(fn), \"r\") == NULL\n", stderr); exit(EXIT_FAILURE); } /* ** Represent each line of the temporary input text file ** as a string in a node of a linked list. */ while ((rc = get_line(&buff, &size, fp)) > 0) { tail = list_append(&head, tail, buff, rc); if (tail == NULL) { fputs("tail == NULL\n", stderr); break; } ++n_lines; } /* ** Close temporary input text file. ** Free allocated buffer used by get_line function. ** Remove temporary input text file. */ fclose(fp); free(buff); remove(fn); /* ** End program if there have been any ** file problems or allocation problems. */ if (rc != EOF) { list_free(head, free); fprintf(stderr, "rc == %d\n", rc); exit(EXIT_FAILURE); } /* ** Display linked list. */ puts("\nInput file:"); list_fputs(head, stdout); /* ** Create array. */ f = malloc(n_lines * sizeof *f); if (f == NULL) { list_free(head, free); fputs("f == NULL\n", stderr); exit(EXIT_FAILURE); } n_fields = 1; for (ptr = head -> data; *ptr != '\0'; ++ptr) { if (*ptr == ' ') { ++n_fields; } } for (line = 0; line != n_lines; ++line) { f[line] = malloc(n_fields * sizeof *f[line]); if (f[line] == NULL) { free_ptrs(f, line); list_free(head, free); fputs("f[line] == NULL\n", stderr); exit(EXIT_FAILURE); } f[line][0] = NULL; } /* ** Tokenize list data and ** assign strings to pointers in array. */ line = 0; for (tail = head; tail != NULL; tail = tail -> next) { f[line][0] = tail -> data; tail -> data = NULL; for (field = 1; n_fields > field; ++field) { f[line][field] = strchr(f[line][field - 1], ' '); if (f[line][field] == NULL) { free_ptrs(f, n_lines); list_free(head, free); fputs("f[line][field] == NULL\n", stderr); exit(EXIT_FAILURE); } *f[line][field]++ = '\0'; } ++line; } /* ** Free list. */ list_free(head, free); /* ** Display resulting array. */ puts("\nResulting array:"); display_array(f, n_lines, n_fields); /* ** Free array. */ free_ptrs(f, n_lines); puts("/* END file_parse.c output */"); return 0; } void display_array(char ***p, size_t n_lines, size_t n_fields) { size_t line, field; for (line = 0; line != n_lines; ++line) { for (field = 0; field != n_fields; ++field) { printf("array[%lu][%lu] ", (long unsigned)line, (long unsigned)field); puts(p[line][field]); } putchar('\n'); } } void free_ptrs(char ***p, size_t nmemb) { while (nmemb-- != 0) { free(p[nmemb][0]); free(p[nmemb]); } free(p); } /* END file_parse.c */