char数组中的C随机字符
C random chars inside char array
我正在制作一个加载小文本文件的 c 程序。我将文本文件的读取内容存储在 char 数组 中。这是加载文件的函数。
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]);
}
}
当 for 循环打印输出时,会发生这种情况。 (这是输出的简化版本,我不想把所有 255 个字符都放在这个问题中。)
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
我不确定是什么原因造成的。
我想知道是什么原因造成的,我该如何解决。
您应该将 buf
打印为:
printf("%s\n", buf);
您看到的垃圾是为 buf
和 malloc
分配的未初始化 RAM 内存,fgets
未触及。
您观察到的并不奇怪,让我们检查一下您的代码:
fgets(buf, 255, (FILE*)fp);
首先没有理由将fp
转换为(FILE*)
。 fp
是用正确的类型定义的,强制转换指针是一个坏习惯,通常会导致代码不可读和错误。
fgets(buf, 255, fp)
尝试从流中读取最多 254 个字符,在第一个 '\n'
处停止。它 return 是指向 buf
的指针,除非无法读取任何字符,在这种情况下缓冲区的内容是不确定的并且 NULL
是 returned。
你应该测试这个 return 值来验证字符确实是从流中读取的,否则缓冲区的内容可能是随机字符,可能已经在堆中了 space 其中 malloc()
找到可用内存。
当fgets()
遇到换行或者如果缓冲区已经存储了254个字符,它会在读取字符后存储一个'[=21=]'
字节和return一个指向缓冲区的指针.超出此 NUL 字节的缓冲区的内容是不确定的,如上所述,它们可能是 NUL 或显然是随机字符,或任何东西......
您应该以这种方式重写循环以仅转储有意义的字符:
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] != '[=11=]'; i++) {
printf("%d - %c\n", i, buf[i]);
}
... // do something else with `buf`
}
fclose(fp);
free(buf);
}
fgets
读取到流的末尾(在本例中为前 254 个字符)或直到遇到第一个 '[=11=]'
。如果您正在阅读任何 '[=11=]'
,您将获得垃圾值作为输出。因此,与其执行循环直到 255,不如执行循环直到找到第一个 '[=11=]'
。
我正在制作一个加载小文本文件的 c 程序。我将文本文件的读取内容存储在 char 数组 中。这是加载文件的函数。
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]);
}
}
当 for 循环打印输出时,会发生这种情况。 (这是输出的简化版本,我不想把所有 255 个字符都放在这个问题中。)
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
我不确定是什么原因造成的。
我想知道是什么原因造成的,我该如何解决。
您应该将 buf
打印为:
printf("%s\n", buf);
您看到的垃圾是为 buf
和 malloc
分配的未初始化 RAM 内存,fgets
未触及。
您观察到的并不奇怪,让我们检查一下您的代码:
fgets(buf, 255, (FILE*)fp);
首先没有理由将fp
转换为(FILE*)
。 fp
是用正确的类型定义的,强制转换指针是一个坏习惯,通常会导致代码不可读和错误。
fgets(buf, 255, fp)
尝试从流中读取最多 254 个字符,在第一个 '\n'
处停止。它 return 是指向 buf
的指针,除非无法读取任何字符,在这种情况下缓冲区的内容是不确定的并且 NULL
是 returned。
你应该测试这个 return 值来验证字符确实是从流中读取的,否则缓冲区的内容可能是随机字符,可能已经在堆中了 space 其中 malloc()
找到可用内存。
当fgets()
遇到换行或者如果缓冲区已经存储了254个字符,它会在读取字符后存储一个'[=21=]'
字节和return一个指向缓冲区的指针.超出此 NUL 字节的缓冲区的内容是不确定的,如上所述,它们可能是 NUL 或显然是随机字符,或任何东西......
您应该以这种方式重写循环以仅转储有意义的字符:
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] != '[=11=]'; i++) {
printf("%d - %c\n", i, buf[i]);
}
... // do something else with `buf`
}
fclose(fp);
free(buf);
}
fgets
读取到流的末尾(在本例中为前 254 个字符)或直到遇到第一个 '[=11=]'
。如果您正在阅读任何 '[=11=]'
,您将获得垃圾值作为输出。因此,与其执行循环直到 255,不如执行循环直到找到第一个 '[=11=]'
。