简体   繁体   English

C 读取文件末尾的随机字符

[英]Random characters at the end of C read file

I've been trying to read a file using code I got from this answer.我一直在尝试使用从这个答案中获得的代码读取文件。

This is my code:这是我的代码:

#include <stdio.h>
#include <stdlib.h>

char * readfile(FILE * f)
{
    char * buffer = 0;
    long length;
    

    if (f)
    {
        fseek(f, 0, SEEK_END);
        length = ftell (f);
        fseek(f, 0, SEEK_SET);
        buffer = malloc(length);
        if (buffer) fread(buffer, 1, length, f);
        fclose(f);
    }

    return buffer;
}

int main()
{
    FILE * f = fopen("./file.txt", "r");
    printf(readfile(f));
}

My function does return the contents of the file but it also returns random characters.我的 function 确实返回文件的内容,但它也返回随机字符。

contents╪▐>c☻ú

And amazingly they seem to change every time I run the code.令人惊讶的是,每次我运行代码时它们似乎都会发生变化。

contents╗╙ÿ▓.┤

The contents of my file are "contents".我的文件的内容是“内容”。

My question is: How can I fix my code for it not to return random characters?我的问题是:如何修复我的代码以使其不返回随机字符?

Strings in C need to be null terminated. C 中的字符串需要 null 终止。 Your buffer string is not terminated when you read the contents.当您读取内容时,您的缓冲区字符串不会终止。 Essentially you are printing the files contents as desired, but the read just keeps on going in contiguous memory until it reaches a null character by chance.本质上,您正在根据需要打印文件内容,但读取只是继续在连续的 memory 中进行,直到偶然到达 null 字符。

My function does return the contents of the file but it also returns random characters.我的 function 确实返回文件的内容,但它也返回随机字符。

No. The function returned only a pointer , not any characters.不。 function 只返回一个指针,而不是任何字符。

It is the printf() call that used that pointer, thinking it was a pointer to a string .使用该指针的是printf()调用,认为它是一个指向string的指针。 In C, a string always contains a final '\0' , else it is not a string.在 C 中,字符串始终包含最终'\0' ,否则它不是字符串。 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.它只是一个指向缺少null 字符的字符数组的指针,并导致未定义的行为,因为printf(s)只知道从哪里开始(在s处),但不知道在哪里结束。

A better approach: return a pointer to a string .更好的方法:返回一个指向字符串的指针。

Best to add error checking too.最好也添加错误检查。

// Let calling code close the file
char *readfile_alt(FILE * f) {
  if (f == NULL || fseek(f, 0, SEEK_END) || (length = ftell(f)) == -1) {
    return NULL;
  }

  char *buffer = length < SIZE_MAX ? malloc(length + 1LU) : NULL;
  if (buffer == NULL || fread(buffer, 1, length, f) != length) {
    free(buffer); 
    return NULL;
  }
  buffer[length] = '\0'; // Now buffer points to a string
  return buffer;
}

Also, printf() expects a format string.此外, printf()需要一个格式字符串。
Better to use printf("%s", readfile(f));最好使用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.
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM