【问题标题】:C, garbage/junk values in string when reading textfileC、读取文本文件时字符串中的垃圾/垃圾值
【发布时间】:2018-02-20 02:04:37
【问题描述】:

我正在尝试在 C 中读取 .txt 文件(paragraph.txt 作为输入),当我打印字符串时,它的末尾有垃圾值,例如我的 Visual Studio 的路径或垃圾数据。 99% 的时间都会出现这种情况,但也有一些例外。我不知道它为什么这样做?

void readfile(char **buffer, char *input)
{
    FILE *file = fopen(input, "r");
    int bytes = filesize(file);
    *buffer = (char*)malloc(bytes);
    fread(*buffer, bytes, 1, file);
    printf("%s\n", *buffer);
    fclose(file);
}

我的文件大小函数只返回文件的字节数,我已经检查过它是正确的(返回 4412 字节,这是我拥有的确切字符数)。 函数调用如下:

readfile(&buffer, input);

【问题讨论】:

  • 你不是在末尾添加一个零值字节吗?
  • @LeeTaylor 我通过 *buffer[bytes-1] = '\0'; 尝试了这个但是当它试图这样做时它只是使程序崩溃:/
  • 第一件事:没有对file 进行空检查,所以你知道文件没有打开,所以你得到了垃圾。
  • @John3136 它仍然显示文本文件,带有 printf。它只是在最后有垃圾。
  • @wrestlerdude c 中的所有字符串都需要以 \0 结尾。您需要比当前多分配一个字节,然后将最后一个字节设置为 0。

标签: c memory-management heap-memory


【解决方案1】:

由于两个错误,它显示“垃圾”:

  1. 您没有为内容分配足够的内存加上 '\0'-终止字节。
  2. 你没有设置'\0'-终止字节。 fread 不会那样做,因为 fread 不关心它正在读取的字节的含义,它只是读取 一块内存,就是这样。

int readfile(char **buffer, const char *input)
{
    if(buffer == NULL)
        return 0;

    FILE *file = fopen(input, "r");
    if(file == NULL)
    {
        fprintf(stderr, "could not open %s for reading: %s\n", input,
                strerror(errno));
        return 0;
    }

    int bytes = filesize(file);

    *buffer = malloc(bytes + 1);
    if(*buffer == NULL)
    {
        fprintf(stderr, "Not enough memory\n");
        fclose(file);
        return 0;
    }

    if(fread(*buffer, bytes, 1, file) != 1)
    {
        fprintf(stderr, "could not read\n");
        free(*buffer);
        *buffer = NULL;
        fclose(file);
        return 0;
    }

    (*buffer)[bytes] = 0; // setting the 0 byte
    puts(*buffer);
    fclose(file);

    return 1;
}

您还应该经常检查函数的返回码,特别是那些 返回指针和/或写入您传递给它们的指针。如果其中之一 函数返回错误,否则您将有未定义的行为。

编辑

在你说的cmets中

我通过 *buffer[bytes-1] = '\0'; 尝试了这个,但是当它尝试这样做时它只是让程序崩溃了

那是因为 buffer[bytes-1] 与 buffer + bytes -1 相同,而这 超出buffer 指向的范围。当您尝试取消引用它时 使用*,它会崩溃。您需要做的(就像我在代码中所做的那样)是: (*buffer)[bytes] = 0; 与 buffer[0][bytes] = 0 相同。

【讨论】:

  • 不同寻常的是,它可以工作,但是......当我连续第二次这样做时,垃圾数据又回来了。
  • 所以问题依然存在。
  • 是的,我有,每次在初始时间之后运行时,它似乎都会在末尾添加“Visual Studio 14.0\Com”。
  • 看来我运气不好,还是谢谢你的尝试。
  • 我用我的代码连续调用了 10 次readfile(&buffer, "/etc/fstab");,最后我没有得到垃圾。你可能在其他地方有另一个未定义的行为,可能在filesize。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
  • 2019-05-23
相关资源
最近更新 更多