My function does return the contents of the file but it also returns random characters.
How can I fix my code for it not to return random characters?
No. The function returned only a pointer, not any characters.
It is the printf() call that used that pointer, thinking it was a pointer to a string. In C, a string always contains a final '\0', else it is not a string. It was only a pointer to a character array lacking a null character and led to undefined behavior as printf(s) only knows where to start (at s), but not where to end.
Do not print past the end of the allocated data.
A better approach: return a pointer to a string. Allocate enough for the data and a final null character and form a string to let printf() know where to stop.
Best to add error checking too.
// Let calling code close the file
char *readfile_alt(FILE * f) {
// f invalid? fseek() fail?
if (f == NULL || fseek(f, 0, SEEK_END)) {
return NULL;
}
long length = ftell(f);
rewind(f);
// Did ftell() fail? Is the length too long?
if (length == -1 || length >= SIZE_MAX) {
return NULL;
}
// Convert from long to size_t
size_t ulength = (size_t) length;
char *buffer = malloc(ulength + 1);
// Allocation failed? Read incomplete?
if (buffer == NULL || fread(buffer, 1, ulength, f) != ulength) {
free(buffer);
return NULL;
}
buffer[ulength] = '\0'; // Now buffer points to a string
return buffer;
}
Also, printf() expects a format string where "%" has special meaning. Better to use printf("%s", readfile(f));.
int main() {
FILE * f = fopen("./file.txt", "r");
if (f) {
char *s = readfile(f);
if (s) {
printf("%s\n", s);
free(s); // Free resource when done with them.
}
fclose(f); // Free resource when done with them.
}
}
Even better code would consider the file may unexpectedly contain null characters. Leave that for another day.