Having an issue with my fwrite() and fread() dealing with a binary file here is my source code, and towards the bottem are my read and write. Right now it is returning ‘jake’ when I run it, and nothing else. I was told to write a dump buffer function to deal with the binary characters. In addition here is the text file as well, I am writing to a blank file called info.bin. PS I know that it is bad practice to save the zip as an int but this is what my professor is asking for.
File:
mike|203-376-5555|7 Melba Ave|Milford|CT|06461
jake|203-555-5555|8 Melba Ave|Hartford|CT|65484
snake|203-555-5555|9 Melba Ave|Stamford|CT|06465
liquid|203-777-5555|2 Melba Ave|Barftown|CT|32154
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LINE 80
#define RECORDS 10
struct info{
char name[100];
char number[100];
char address[100];
char city[100];
char state[100];
int zip;
};
void dump_buffer(void *buffer, int buffer_size)
{
int x;
for(x = 0; x < buffer_size; x++)
{
printf("%c",((char *)buffer)[x]);
}
}
int i, j, seeker;
int main(int argc, char* argv[])
{
char *buffer;
struct info input_records[RECORDS];
int nrecs = 0;
unsigned long fileLen;
char line[LINE];
FILE *fp = NULL;
FILE *fpbin = NULL;
FILE *fpread = NULL;
if (argc != 2)
{
printf ("ERROR: you must specify file name!\n");
return 1;
}
/* Open file */
fp = fopen(argv[1], "r");
if (!fp)
{
perror ("File open error!\n");
return 1;
}
while (!feof (fp)) {
fgets(line, sizeof(line),fp);
char* tok = strtok(line, "|");
while(tok != NULL)
{
strcpy(input_records[nrecs].name, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].number, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].address, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].city, tok);
tok = strtok(NULL, "|");
strcpy(input_records[nrecs].state, tok);
tok = strtok(NULL, "|");
input_records[nrecs].zip = atoi(tok);
tok = strtok(NULL, "|");
}
nrecs++;
}
fpbin = fopen("info2.bin", "wb");
if (!fp)
{
perror ("File open error!\n");
return 1;
}
for(i = 0; i < 4; i++)
{
fwrite(&input_records[i], sizeof(struct info), 200000, fpbin);
}
fclose(fpbin);
fpread = fopen("info2.bin", "rb");
fseek(fpread, 0, SEEK_END);
fileLen = ftell(fpread);
fseek(fpread, 0, SEEK_SET);
buffer = (char *)malloc(sizeof(struct info));
fread(buffer, fileLen, 1, fpread);
dump_buffer(buffer, sizeof(buffer));
fclose(fpread);
fclose(fp);
free(buffer);
return 0;
}
You just told
fwriteto write200000 * sizeof(struct info)bytes to the file, starting at the address ofinput_records[i]. That accesses memory far beyond what has been allocated forinput_records, the behaviour is undefined, but a segmentation fault is not unlikely. I’m actually surprised that apparently it didn’t crash for you.You’re trying to read
fileLenbytes into a buffer of sizesizeof(struct info). IffileLen > sizeof(struct info), that is again undefined behaviour, and iffileLenis sufficiently larger, likely to crash.You should let
fwriteone object of sizesizeof(struct info)each time, and you should allocatefileLenbytes for the buffer you read in (or read in chunks of sizesizeof(struct info)). And you should check the return values offwriteandfreadto know whether they succeeded in writing/reading the desired data and handle failures appropriately.You check the wrong
FILE*here, and you don’t checkfpreadat all.Further, you pass the wrong count to
dump_buffer,bufferis achar*, sosizeof bufferis the size of achar*, typically four or eight bytes. You should pass the allocated size of the buffer there.And, when reading the original file,
feof(fp)only becomes true after an attempt to read was made when the end of the file has been reached, you should change your loop condition toFinally, your tokenizing code will fail badly if the input file contains malformed data, or too long lines. You should also add checks there, so that you don’t pass a
NULLtostrcpyoratoi.