在Mac上,C语言的Clang代码执行失败,且没有错误信息。它只是输出“2”,然后是一个文件的前两个字符

编程语言 2026-07-11

程序的工作方式是,它先在新的一行输出 "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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章