Reputation: 23
Can't seem to work out why this code is not working. It should be really straight forward. From what I have troubleshooted, in the while(token) block the id array is assigned but then when I go to print all the char array's outside the while(token) block the id array displays nothing but all the other array's display their contents.
int loadCatData(char* menuFile) {
char line[MAX_READ];
char id[ID_LEN];
char hotCold[MIN_DESC_LEN];
char name[MAX_NAME_LEN];
char description[MAX_DESC_LEN];
char delim[2] = "|";
char lineTemp[MAX_READ];
int count;
FILE *mfMenu = fopen(menuFile, "r");
while (fgets(line, sizeof(line), mfMenu)!=NULL) {
count = 0;
printf(line);
strcpy(lineTemp,line);
char* token = strtok(lineTemp, delim);
while (token) {
printf(token);
if (count == 0) {
strcpy(id, token);
}
if (count == 1) {
strcpy(hotCold, token);
}
if (count == 2) {
strcpy(name, token);
}
if (count == 3) {
strcpy(description, token);
}
printf("\n");
token = strtok(NULL, delim);
count = count + 1;
}
printf(id);
printf(hotCold);
printf(name);
printf(description);
}
fclose(mfMenu);
return true;
}
Upvotes: 1
Views: 1010
Reputation: 249153
int loadCatData(const char* menuFile) {
char id[ID_LEN];
char hotCold[MIN_DESC_LEN];
char name[MAX_NAME_LEN];
char description[MAX_DESC_LEN];
FILE *mfMenu = fopen(menuFile, "r");
while (fscanf(mfMenu, "%*s|%*s|%*s|%*s",
sizeof(id), id, sizeof(hotCold), hotCold,
sizeof(name), name, sizeof(description), description) == 4) {
printf("%s %s %s %s\n", id, hotCold, name, description);
}
fclose(mfMenu);
return true;
}
You should never pass input from outside the program to printf as the first argument. Imagine if one of the tokens is "%s" and you say printf(token)--that's undefined behavior because you didn't pass a second string to print, and your program will crash if you're lucky.
Upvotes: 1
Reputation: 8097
You are the victim of a buffer overflow error caused by strcpy
.
What is happening is that the hotCold
array is too small to hold the data you're filling it with, but strcpy
doesn't care, nor does it know that there isn't enough room. So it keeps on writing data into hotCold
and then runs out of room, then fills up the padding bytes, then fills up id
. You just have the unfortunate luck of having the terminating null byte of hotCold
sitting at the start of id
.
Switch from using strcpy
to strncpy
or strncat
(which I think is better than strncpy
). If you're skeptical of what I'm saying, add a line of code at the end that goes like this:
assert (strlen (hotCold) < MIN_DESC_LEN);
The other alternative is that the id
field is being interpreted as a special printf
-format specifier. Just in case, replace printf(id)
with printf("%s", id)
.
Upvotes: 1