简体   繁体   English

文件末尾是否有一个终止字符(不是 EOF),它将作为最后一个字符读取?

[英]Is there a terminating character (NOT EOF) at the end of the file which will be read as the last char?

I was trying to read a file into a string with the following code.我试图使用以下代码将文件读入字符串。 I assigned 5 bytes for the char *a and actually read a file with more than 5 chars.我为char *a分配了 5 个字节,并实际读取了一个超过 5 个字符的文件。 However, the output still print the correct file contents without any garbage value or missing value.但是,output 仍然打印正确的文件内容,没有任何垃圾值或缺失值。

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

#define INPUT_SIZE 5

int main() {

        char *a = malloc(INPUT_SIZE);
        FILE *fp = fopen("text", "r");
        if (fp == NULL) {
                perror("Unable to open the file");
        }

        char *b = a;
        char c;
        int i = 0;
        while ((c = fgetc(fp)) != EOF) {
                *b++ = c;
        }

        printf("%s", a);
        free(a);
        fclose(fp);
        return 0;
}

The input file is输入文件是

abc
def
g

And the output is exactly the same as the input file.而output和输入文件完全一样。
Since normally there should be a '\0' at the end of the char * to show where the string end.因为通常在char *的末尾应该有一个 '\0' 来显示字符串的结束位置。 But in this occasion, there is no explicit '\0' in the char *a .但在这种情况下, char *a中没有明确的 '\0' 。 So I wonder if there is an '\0' at the end of the file which was read as the last char?所以我想知道文件末尾是否有一个'\0'作为最后一个字符读取?

This is a situation where the results may look correct, but you are simply getting "lucky" with the output of your program.在这种情况下,结果可能看起来是正确的,但您只是对程序的 output 感到“幸运”。

First, when you call malloc(INPUT_SIZE) , your implementation of libc will generally not allocate just 5 bytes, but actually some multiple of 8 bytes (like 16 or 32, depends on the platform [see unexpected output of size allocated by malloc in C ). First, when you call malloc(INPUT_SIZE) , your implementation of libc will generally not allocate just 5 bytes, but actually some multiple of 8 bytes (like 16 or 32, depends on the platform [see unexpected output of size allocated by malloc in C )。 This extra data contains possible padding bytes after your data and metadata before and after your requested block.这个额外的数据在您请求的块之前和之后的数据和元数据之后包含可能的填充字节。 This is done for alignment and bookkeeping purposes, but the takeaway is that you get more than you ask for when you call malloc .这是为 alignment 和簿记目的而完成的,但要点是,当您调用malloc时,您得到的比您要求的要多。

You should not take advantage of this implementation detail to fit more data into a malloc ed region that you requested as that space is not really yours for the taking.您不应利用此实现细节将更多数据放入您请求的malloc ed 区域,因为该空间并不是您真正的空间。 By writing past the end of your buffer, you risk scribbling on important data that your allocator needs to ensure consistency.通过写入超过缓冲区的末尾,您可能会在分配器需要确保一致性的重要数据上乱涂乱画。

Second, the null terminator behavior you are seeing is simply you getting lucky and receiving a zeroed out section of memory from malloc .其次,您看到的 null 终结器行为只是您很幸运并从 malloc 收到malloc的归零部分。 This is not always guaranteed, and the next time you run the program, your buffer could come back from malloc filled with random values, instead of 0 .这并不总是得到保证,下次您运行程序时,您的缓冲区可能会从malloc中返回,其中填充了随机值,而不是0 If you want pre-zeroed memory, use calloc instead.如果您想要预置零 memory,请改用calloc

So to answer the question, no there is not a null terminator at the end of files, your program is just using undefined behaviors of the standard library to make it look like there is.所以要回答这个问题,不,文件末尾没有 null 终止符,您的程序只是使用标准库的未定义行为使其看起来像存在。

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

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