C数组中的C随机字符

时间:2015-07-04 16:16:52

标签: c arrays char malloc

我正在制作一个加载小文本文件的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

我不确定是什么原因造成的。
我想知道造成这种情况的原因以及如何解决这个问题。

3 个答案:

答案 0 :(得分:5)

您应该将buf打印为:

printf("%s\n", buf);

您看到的垃圾是未经初始化的RAM内存,为buf分配了malloc而未被fgets触及。

答案 1 :(得分:1)

你观察到的并不奇怪,让我们检查你的代码:

fgets(buf, 255, (FILE*)fp);

首先,没有理由将fp投射到(FILE*)。使用正确的类型定义fp,并且指针是一个坏习惯,通常会导致代码不可读和错误。

fgets(buf, 255, fp)尝试从流中读取最多254个字符,并在第一个'\n'处停止。它返回一个指向buf的指针,除非无法读取任何字符,在这种情况下缓冲区的内容是不确定的,并返回NULL

您应该测试此返回值以验证确实是从流中读取了字符,否则缓冲区的内容可能是随机字符,可能发生在malloc()找到可用内存的堆空间中的情况

fgets()遇到换行符或者缓冲区中存储了254个字符时,它会在读取字符后存储'\0'个字节并返回指向缓冲区的指针。超出这个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] != '\0'; i++) {
            printf("%d - %c\n", i, buf[i]);
        }
        ...  // do something else with `buf`
    }
    fclose(fp);
    free(buf);
}

答案 2 :(得分:0)

fgets读取直到流的末尾(在这种情况下为前254个字符)或直到遇到第一个'\0'。如果您正在阅读任何'\0',您将获得垃圾值作为输出。因此,不应该执行循环直到255,而是应该只执行它直到找到第一个'\0'