[英]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.