As an exercise to improve my coding ability in C, I have attempted to write a simple and safe file reader. I believe this should be portable as well to major platforms (correct me if I'm wrong). For simplicity's sake I assume the file will fit in memory which is mostly true for my use case.
Please let me know where I can improve.
(Note: I've used goto
because I think it makes the code flow better)
int read_file(const char* filename, char** buffer) { FILE* fp = fopen(filename, "r"); if (!fp) { goto f_read_error; } ssize_t file_len; if (fseek(fp, 0L, SEEK_END) == 0) { file_len = ftell(fp); if (file_len == -1) { goto f_read_error; } if (fseek(fp, 0L, SEEK_SET) != 0) { goto f_read_error; } *buffer = (char*) malloc(sizeof(char) * (file_len + 1)); int output = fread(*buffer, sizeof(char), file_len, fp); if (output != file_len) { goto f_read_error; }; (*buffer)[file_len] = '\0'; } else { f_read_error: ; char error_msg[1024]; // let's trunc filenames larger than 256, to not overflow error_msg buffer char safe_filename[256]; if (strlen(filename) > 256) { memcpy(safe_filename, filename, 256); } sprintf(error_msg, "Unable to read file : %s", safe_filename); perror(error_msg); if (buffer) { free(buffer); } if (fp) { fclose(fp); } return -1; } if (fp) { fclose(fp); } return 1;}int main(int argc, char** argv) { char* source = NULL; int success = read_file("test.txt", &source); if (success) { //read_file("test.txt", &source); - a copy paste error, edited as a comment printf("%s\n", source); free(source); }}