Reputation: 13
I have this code that takes a file "schedule.txt" and let's the user enter a class in and it displays the time the class is at, unfortunately I am having difficulties with the tokenizing...
int main(int argc, char *argv[])
{
// Declare variables
FILE *inp = NULL;
char str[200];
char class[7][20];
double times[15];
double times2[15];
int i;
const char delim[] = " 0123456789:";
// Open the file, quit if it fails...
inp = fopen(argv[1], "r");
if(inp == NULL){
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(1);
}
// Read the file and tokenize it for names of classes and times
i = 0;
while(fgets(str, 200, inp) != NULL){
str[strlen(str)-1] = '\0';
char *classToken = strtok(str, "0123456789");
strcpy(class[i], classToken);
char *timeToken = strtok(NULL, " ");
times[i] = atof(timeToken);
i++;
}
for(i = 2; i < 6; i++){
printf("%f\n", times[i]);
}
return 0;
}
I wish to tokenize the file into two different arrays, one containing the string of the class, and the other being the times without the ":", but when I have the delimiter as the numbers it doesn't let me use the first number of the time, but when the delimiter is " " the string array contains the times as well, how could I do this? The file looks like this:
Class Schedule
Class Time
Physics 15:30
Calculus 9:00
Biology 14:30
Chemistry 11:30
Upvotes: 0
Views: 98
Reputation: 40155
The main problem is that the delimiter is inappropriate.
Specifically, It will tokenize as follows.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct schedule {
char className[20];
int time;//minute
}Schedule;
int main(int argc, char *argv[]) {
FILE *inp;
char line[200];
char title[32];
char fieldName[2][20];
Schedule schedule[7];
int i;
if(argc != 2){
fprintf(stderr, "Usage : %s filename\n", argv[0]);
exit(1);
}
inp = fopen(argv[1], "r");
if(inp == NULL){
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(1);
}
fgets(title, sizeof title, inp);
fgets(line, sizeof line, inp);
char *token;
token = strtok(line, " \t\n");
strcpy(fieldName[0], token);
token = strtok(NULL, " \t\n");
strcpy(fieldName[1], token);
i = 0;
while(i < 7 && fgets(line, sizeof line, inp)){
token = strtok(line, " \t\n");//maybe "\t\n"
strcpy(schedule[i].className, token);
token = strtok(NULL, " \t\n");
schedule[i].time = atoi(token)*60 + atoi(strchr(token, ':')+1);//"hh:mm" : hh * 60 + mm
i++;
}
int n = i;
printf("%s", title);
printf("%-20s%s\n", fieldName[0], fieldName[1]);
for(i = 0; i < n; i++){
printf("%-20s%02d:%02d\n", schedule[i].className, schedule[i].time/60, schedule[i].time%60);
}
return 0;
}
Upvotes: 0
Reputation: 409472
There are two problems you have: The first is that strtok
modifies the string, and replaces the found token separator with the string terminator.
So if your input string looks like "Physics 15:30"
the after the first call to strtok
it will have been modified to look like "Physics \05:30"
.
The solution to this is to use space (or tab, or both) as the token separator, and then skip spaces when getting the next token.
The second problem is that you use atof
to get the time. A time is not a floating-point value, especially no current numbering system uses :
to separate the integer and fraction part. Not to mention that 15:30
as a floating point number would be 15.30
which is not the same as 15.50
(which in turn is not the same as the time 15:50
).
An easy solution for both problems is to use sscanf
instead to parse the line into two strings.
Upvotes: 1