-
Incorrect Input
I finally got to a computer with a compiler and played around with everything I've learned so far on a school project. Everything works beautifully except for one small problem that kills the program. After debugging I found the source of the problem but I'm not sure how to solve it.
Code:
struct Cust{
char * recordBuf[7];
char * addr[4];
}Rec[30];
FILE * IN;
void readRecord(struct Cust * Rec);
int main(void){
IN = fopen("SUPPLY.TXT", "r");
readRecord(Rec);
return 0;
}
void readRecord(struct Cust * Rec){
char buffer[1024], *token = 0;
char delim[2] = {' '};
int i, j = 0;
while(!feof(IN)){
fgets(buffer, sizeof(buffer), IN);
token = strtok(buffer, delim);
for(i = 0; i < 7; i++){
Rec[j].recordBuf[i] = malloc(60 * sizeof(char));
Rec[j].recordBuf[i] = token;
token = strtok(NULL, delim);
}
for(i = 0; i < atoi(Rec[j].recordBuf[6]); i++){
Rec[j].addr[i] = malloc(30 * sizeof(char));
fgets(Rec[j].addr[i], sizeof(Rec[j].addr[i]), IN);
}
j++;
}
}
The problem is in my second fgets call
Code:
fgets(Rec[j].addr[i], sizeof(Rec[j].addr[i]), IN);
Assuming the input is
10463 Davis Alice Joliet MD 26361 1
2713 Longlake Drive
The first loop will read the first line and break it up into the proper tokens. Except the last token, which seems to be reading both the 1 and the newline instead of ignoring the newline and exiting the loop.
Then the second loop only reads the first three characters when it should be reading the entire line.
This is rather a big problem because I have a large file of these lines and if the input isn't perfect I'll get an access error from fgets.
Any ideas as to why this is happening?
-
> while(!feof(IN)){
> fgets(buffer, sizeof(buffer), IN);
Should be
while( fgets(buffer, sizeof(buffer), IN) != NULL ) {
Reason:
feof() doesn't return true when you've read the last character from the file, it returns true when some other read function (eg fgets) has returned true.
Code:
for(i = 0; i < 7; i++){
Rec[j].recordBuf[i] = malloc(60 * sizeof(char));
Rec[j].recordBuf[i] = token;
token = strtok(NULL, delim);
}
Should be
Code:
for(i = 0; i < 7; i++){
Rec[j].recordBuf[i] = malloc(60 * sizeof(char));
strcpy( Rec[j].recordBuf[i], token );
token = strtok(NULL, delim);
}
Rec[j].recordBuf[i] = token; does not copy the string, it just copies the pointer (and you lose the memory you allocated).
Code:
for(i = 0; i < atoi(Rec[j].recordBuf[6]); i++){
Rec[j].addr[i] = malloc(30 * sizeof(char));
fgets(Rec[j].addr[i], sizeof(Rec[j].addr[i]), IN);
}
Should be
Code:
for(i = 0; i < atoi(Rec[j].recordBuf[6]); i++){
Rec[j].addr[i] = malloc(30 * sizeof(char));
fgets(Rec[j].addr[i], 30, IN);
}
sizeof(Rec[j].addr[i]) is the size of the pointer (typically 4 bytes), not the size of the amount of memory it points to.