在Mac上,C语言的Clang代码执行失败,且没有错误信息。它只是输出“2”,然后是一个文件的前两个字符
程序的工作方式是,它先在新的一行输出 "2",接着输出一个文件中的前两个字符。看起来有些奇怪,因为程序本身似乎没有明显错误。我试着简化程序,但即便在简化后的形式也会失败。
我现在考虑放弃。这甚至不是玩笑,我只是不确定我的电脑出了什么问题,会让这段代码编译不通过。 (我已经尝试了错误处理——没有错误)。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef int32_t i32;
int main(int argc, char **argv) {
FILE *file = fopen("Makefile", "rb");
fseek(file, SEEK_END, 0);
i32 filesize = ftell(file);
fseek(file, SEEK_SET, 0);
fprintf(stderr, "%u\n", filesize);
char *text = malloc(filesize + 1);
fread(text, 1, filesize, file);
fprintf(stderr, "%s", text);
fclose(file);
return 0;
}
解决方案
fseek(file, SEEK_END, 0) 是错的。fseek 的参数是 流、偏移量,以及“whence”(从哪里开始),按这个顺序。应该是 fseek(file, 0, SEEK_END)。同样,fseek(file, SEEK_SET, 0) 应该是 fseek(file, 0, SEEK_SET)。
在macOS上使用Apple的工具时,SEEK_SET 为0,SEEK_END 为2。因此 fseek(file, SEEK_END, 0) 为 fseek(file, 2, 0),这表示从起点向前跳2 个字节。然后 ftell 返回2,你的程序只读取了两个字节。
不要在仅用于练习的学生程序之外,使用这种方法来确定文件大小。文件的内容会不时变化,可能在你执行 fseek 和执行 fread 之间发生变化。读取文件内容的正确方法是,先读入一部分,处理这部分内容;再读取、处理,直到读取操作返回没有更多可读内容为止。
你的程序为文件内容分配了空间,将数据读入这块空间,并把这块空间连同 %s 说明符一同传给 fprintf。该说明符期望用一个空字符来标记字符串的结束,但你的程序并没有在分配的空间里写入空字符。它应该在读取的数据之后放入一个空字符,或者使用打印数据的其他方法,例如 fwrite。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。