Reputation: 710
I have written this code to play around with files, its reading a file in chunks of 256 byte
#include <stdio.h>
#include <stdlib.h>
#define CHUNK_SIZE 256
int chunkable(size_t size, int chunk_size){
return (size - chunk_size) > 0;
}
char * read_file(FILE *f, size_t fsize){
char * fbuff = (char *) malloc(sizeof(char) * fsize);
if(chunkable(fsize, CHUNK_SIZE)){
while(fsize > 0){
printf("reading chunk..., remaining: %d\n", fsize);
fread(fbuff, CHUNK_SIZE, 1, f);
fsize -= CHUNK_SIZE;
}
} else {
fread(fbuff, CHUNK_SIZE, 1, f);
}
return fbuff;
}
int main(int argc, char *argv[]){
FILE * f;
int fsize;
char * file_content;
if(argc == 1){
fprintf(stderr, "argument missing (filename) exiting...\n");
return -1;
}
f = fopen(argv[1], "r");
if(f == NULL){
fprintf(stderr, "couldent open %s, exiting...\n", argv[1]);
return -1;
}
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_SET);
file_content = read_file(f, fsize);
printf("file content: %s\n", file_content);
free(file_content);
fclose(f);
}
the problem I have its with this line
while(fsize > 0){...}
every time a chunk is read from a file it subtract the chunk size from the remaining bytes to read, the while loop suppost to stop the read when there are no remaining bytes to read, but the output i am getting is
reading chunk..., remaining: 580
reading chunk..., remaining: 324
reading chunk..., remaining: 68
reading chunk..., remaining: -188
reading chunk..., remaining: -444
reading chunk..., remaining: -700
reading chunk..., remaining: -956
reading chunk..., remaining: -1212
reading chunk..., remaining: -1468
etc...
the fsize
is a negative number which means fsize > 0
is false
but the while loop keeps going 4ever
Upvotes: 1
Views: 62
Reputation: 223689
size
is of type size_t
which is an unsigned type. So as you continue to subtract CHUNK_SIZE
from size
, the value wraps around to a very large positive value.
The reason you see a negative value when you print is because you're using the wrong format specifier to printf
. %d
expects an int
argument. You should be using %zu
instead for size_t
.
You're also not checking the return value of fread
. You could be reading less than CHUNK_SIZE
bytes, or you could be getting an error. You also read into the same buffer every time, overwriting what was previously there.
You need to capture the return value and check it. Based on that, you subtract from size
and also add an offset to fbuff
to append to what you've already read.
char *p = fbuff;
while(fsize > 0){
printf("reading chunk..., remaining: %zu\n", fsize);
size_t len = fread(p, CHUNK_SIZE, 1, f);
if (len == 0) {
printf("error reading\n");
break;
}
fsize -= len;
p += len;
}
*p = 0; // null terminate the string for printing
Upvotes: 4