ftell 返回不准确的值

ftell returning inaccurate value

所以,我在 c 中有这段代码应该从 ascii 文件中读取,然后 return 一个字符串被解析并编译成字节码。当我尝试使用 ftell 获取文件大小时,它 returns 33 而不是 29(文件包含新行的字节数)。

文件:

push #25
nop
push #44
add
hlt

代码:

uint8_t* read_ascii_file(uint8_t* path) {
    FILE* file = fopen(path, "r");
    if (file == NULL)
        return NULL;
    fseek(file, 0, SEEK_END);
    uint32_t size = ftell(file);
    fseek(file, 0, SEEK_SET);
    uint8_t* buffer = (uint8_t*)malloc(sizeof(uint8_t) * size);
    if (buffer == NULL)
        return NULL;
    fread(buffer, sizeof(uint8_t), size, file);
    buffer[size] = '[=11=]';
    fclose(file);
    return buffer;
}

似乎无缘无故地添加了四个字节。我的解析器抱怨“hlt====”不是有效指令(“====”是 4 个额外字节)。

Ftell 或 fseek 在这种情况下搞砸了,我不知道这是不是一个错误

我正在使用 Windows,我也在使用 visual studio

您分配的资源不足 space。

您为文件内容分配了 sizeof(uint8_t) * size 字节,但这不足以容纳您稍后添加以终止字符串的空字节。所以你写超出了分配内存的界限,触发 undefined behavior.

加 1 留下 space 作为空终止符。

uint8_t* buffer = (uint8_t*)malloc(sizeof(uint8_t) * size + 1);

此外,这些行有问题:

fread(buffer, sizeof(uint8_t), size, file);
buffer[size] = '[=11=]';

由于 windows 上的换行符转换,您最终读取的字节数将少于文件实际包含的字节数。这意味着终止空字节在错误的位置。

保存 fread 的 return 值,它会告诉您 实际上 读取了多少字节,然后使用该值写入空字节。

size_t rval = fread(buffer, sizeof(uint8_t), size, file);
if (rval > 0) {
    buffer[rval] = '[=12=]';
}