C random characters inside char array
I am making a c program that downloads a small text file. I am storing the contents of a text file read in a char array . Here is the function that loads the file.
void load_text_file(char* filename) {
FILE *fp;
char *buf = malloc(255 * sizeof(char));
if (!buf) return NULL;
fp = fopen(filename, "r");
fgets(buf, 255, (FILE*)fp);
int i;
for(i=0;i<255;i++) {
printf("%d - %c\n", i, buf[i]);
}
}
This happens when the for loop prints the output. (This is a shortened version of the output; I didn't want to fit all 255 characters in this question.)
0 - H
1 - e
2 - l
3 - l
4 - o
5 -
6 - W
7 - o
8 - r
9 - l
10 - d
11 - !
//Random chars past this point
12 -
13 -
14 - โ
15 -
16 - โ
//etc... etc... etc...
96 - ร
97 -
98 -
99 - ร
100 - รฅ
101 - รจ
102 -
//etc... etc... etc...
//all the way up to 255 chars
I'm not sure what is causing this.
I want to know what is causing this and how I can fix it.
source to share
What you are seeing is not surprising, let's take a look at your code:
fgets(buf, 255, (FILE*)fp);
There is no reason to throw fp
in at first (FILE*)
. fp
is defined with the correct type, and cast pointers is a bad habit that often leads to unreadable and erroneous code.
fgets(buf, 255, fp)
tries to read up to 254 characters from the stream, stopping at the first '\n'
. It returns a pointer to buf
, unless no characters can be read, in which case the contents of the buffer will be undefined and returned NULL
.
You must check this return value to ensure that the characters were actually read from the stream, otherwise the contents of the buffer may be a random character, possibly already on the heap where malloc()
available memory was found.
When fgets()
encountered with a line feed, or if there are 254 characters in the buffer, it stores the bytes '\0'
after reading the characters and returns a pointer to the buffer. The contents of the buffer behind this NUL byte are undefined, as stated above, they could be NUL, or seemingly random characters, or anything at all ...
You should rewrite your loop to only erase significant characters:
void load_text_file(const char *filename) {
char *buf = malloc(255 * sizeof(char));
if (!buf) { printf("could not allocate memory\n"); return; }
FILE *fp = fopen(filename, "r");
if (!fp) { printf("could not open file\n"); return; }
if (fgets(buf, 255, (FILE*)fp)) {
for (int i = 0; buf[i] != '\0'; i++) {
printf("%d - %c\n", i, buf[i]);
}
... // do something else with `buf`
}
fclose(fp);
free(buf);
}
source to share