c - ftell 返回不准确的值
问题描述
所以,我在 c 中有这段代码,它应该从一个 ascii 文件中读取,然后返回一个被解析并编译成字节码的字符串。当我尝试使用 ftell 获取文件的大小时,它返回 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] = '\0';
fclose(file);
return buffer;
}
似乎无缘无故地又添加了四个字节。我的解析器抱怨“hlt====”不是一个有效的指令(“====”是 4 个额外的字节)。
Ftell 或 fseek 在这种情况下搞砸了,我不知道这是否是错误
我在 Windows 上,我也在使用 Visual Studio
解决方案
你没有分配足够的空间。
您为文件内容分配sizeof(uint8_t) * size
字节,但这不足以保存您稍后添加以终止字符串的空字节。所以你写超出了分配内存的范围,触发了未定义的行为。
加 1 为空终止符留出空间。
uint8_t* buffer = (uint8_t*)malloc(sizeof(uint8_t) * size + 1);
此外,这些行是有问题的:
fread(buffer, sizeof(uint8_t), size, file);
buffer[size] = '\0';
由于 Windows 上换行符的翻译,最终读取的字节数会少于文件实际包含的字节数。这意味着终止的空字节位于错误的位置。
保存它的返回值fread
将告诉您实际读取了多少字节,然后使用该值写入空字节。
size_t rval = fread(buffer, sizeof(uint8_t), size, file);
if (rval > 0) {
buffer[rval] = '\0';
}
推荐阅读
- javascript - 仅在滚动时显示 Div 并且元素在动态列表中可用
- r - 如何获得闪亮的服务器用户名?
- mysql - 隔行选择和转置:密集等级,效率?
- reactjs - react tbody 上的关键道具警告
- rust - 在异步 rust 中处理重复插入数据库
- python - MySQLClient 不会通过 pip 在最新版本的 Big Sur 的 Macbook Pro M1 上安装
- laravel - 如何用 pm2 运行 laravel 项目?
- flutter - Flutter:如何使小部件始终在阴影之上
- reactjs - 解析错误:“parserOptions.project”已为@typescript-eslint/parser 设置。该文件与您的项目配置不匹配:.eslintrc.js
- python - 如何修复烧瓶运行与 python run.py 之间的导入