For given representation,
typedef struct {
int age;
char *firstName;
char *lastName;
}Record;
and given file.txt
,
Age,LastName,FirstName
50,B,A
30,A,B
20,X,D
10,F,A
90,V,E
60,N,M
Below is the code in main()
,
pFile=fopen("file.txt", "r");
...
//Complete file is copied to 'readBuffer', approach inspired from
// http://stackoverflow.com/a/11487960/3317808
....
char *record = strtok(readBuffer,"\n"); //Ignore header record
record = strtok(NULL, "\n");// Read first data record(50,'B','A')
for(;record != NULL; record = strtok(NULL,"\n")){
printf("###Print complete record\n");
puts(record);
Record *r = malloc(sizeof(Record)*1);
r->age = atoi(strtok(record,","));
char *firstName = strtok(NULL,",");
char *lastName = strtok(NULL, ",");
r->firstName = strdup(firstName);
r->lastName = strdup(lastName);
printf("Age: %d\n", r->age);
printf("First name: %s\n", r->firstName);
printf("Last name: %s\n", r->lastName);
}
strtok(readBuffer,",")
confuses compiler with strtok(record,",")
in for-loop
Actual output shows that tokenisation happened for only one record.
$ ./program.exe
Print complete file
Age,LastName,FirstName
50,B,A
30,A,B
20,X,D
10,F,A
90,V,E
60,N,M
###Print complete record
50,B,A
Age: 50
First name: B
Last name: A
How to resolve it?
As @David C. Rankin suggested, using
fgets
along withstrtok
to read each line is a good approach to this problem.If you want to use
mergesort
in the future, then storing your data in an array of structs would be easiest to implement with this sorting algorithm. Furthermore, if you don't know how many lines will be in the file, then you might need to dynamically allocate this on run-time.You can have a lower-level
struct
storing each line in the file:And a higher-level
struct
storing all contents of the file:Things to note about fgets:
\n
character at the end of buffer, before the null-terminator\0
. This appended\n
can be removed easily though.NULL
. IfEOF
is reached and no characters have been read, then this also returnsNULL
.stdin
or fromFILE *
.Optional usage of fgets in a program:
When using
fgets()
, you can call it once to consume the header information:Then, you can call it again in a
while()
loop, to consume the rest of the data in the file:Implementation of all these ideas in a Program:
Note: I used
malloc()
+strcpy()
instead ofstrdup()
, because they come from standard C libraries like<string.h>
and<stdlib.h>
, instead of POSIX C.Program output: