二进制文件读取错误,是endian问题还是文件读取问题?

0?人关注

目前,我正在研究一个简单的c虚拟机的启动,它将一个二进制文件读入一个 "内存 "数组,然后将获取解码和评估所给的指令。目前,我被困在如何正确地将这个二进制文件读入内存中,以便以后用于解码和基于2或4字节的分离。我的输入与我的输出不匹配,我把它放在下面,我不确定这是否是一个endian问题或我没有正确地把文件读入内存。

MAIN.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXMEM 1024

unsigned memory[MAXMEM];

int loads(char *filename)
{
    File *file = fopen(filename, "rb");
    return fread(memory, sizeof *memory, MAXMEM, file);
}

int main(int argc, char **argv){
    if(argc <= 1){
        printf("No file Found\n");
        return -1;
        }
    char *filename = argv[1];
    loads(filename);
    printf("%04x\n", *memory);
}

INPUT.BIN(从运行od -x --endian=big input.bin | head -5 得到的数据)

00000000 b10a b200 1123

目前的输出

b20ab1

希望的输出

either b10a b200 1123 
or b1 0a b2 00 11 23
7?个评论
我认为你要sizeof(unsigned) 。你的打印方式也很奇怪。实际上你只打印了第一个元素,也就是00 b2 0a b1 printf不会打印前导零,所以是b20ab1 。再用memory[1] 来打印,看看会发生什么。
请注意,函数:fread() 返回一个size_t ,而不是一个int
关于这个表达式。 sizeof *memory, 这是在询问memory 所指向的字节数 不是一个好主意,尤其是memory 不是一个指针。建议使用。sizeof memory
关于:在函数:main() loads(filename);loads() 的签名是:int loads(char *filename) (其中,BTW:不是正确的返回类型),main() 函数忽略了返回值的信息。
加:一般来说,当用户没有提供所需的命令行参数时,代码通常会显示一个类似于usage 的语句。 fprintf( stderr, "USAGE: %s inputFileName\n", argv[0] );
关于。 File *file 这第一个File ,应该是。 FILE 你的编译器没有告诉你这个问题吗?
OT:关于:FILE *file = fopen(filename, "rb"); (注意我把返回的类型大写了)总是检查(!=NULL)返回值以确保操作成功。 如果不成功,则调用perror( "fopen failed" ); ,这样所附的错误信息和系统认为发生错误的文本原因都会输出到stderr
c
binary
virtual-machine
filereader
Bret Hasel
Bret Hasel
发布于?2020-03-26
1?个回答
user3629249
user3629249
发布于?2020-03-26
已采纳
0?人赞同

显示问题都在这个声明中。

printf("%04x\n", *memory);

首先使用一个代表你想显示的格式的字符串。 也许。

"%02x %02x %02x $02x\n"

下面提出的代码。

  1. 清晰地编译了
  2. 执行所需的功能
  3. 正确处理I.O错误
  4. 不包括那些不使用的头文件

而现在,建议的代码。

#include <stdio.h>
//#include <string.h>
#include <stdlib.h>  // exit(), EXIT_FAILURE

#define MAXMEM 1024

char memory[MAXMEM];

size_t loads(char *filename)
{
    FILE *file = fopen(filename, "rb");
    if( !file )
    {
        perror( "fopen for read failed" );
        exit( EXIT_FAILURE );
    }

    return  fread(memory, sizeof *memory, MAXMEM, file);
}

int main(int argc, char **argv){

    if( argc != 2 )
    {
        fprintf( stderr, "USAGE: %s inputFileName\n", argv[0] );
        exit( EXIT_FAILURE );
    }

    char *filename = argv[1];
    size_t fileSize = loads(filename);
    printf( "File Size: %zu\n", fileSize );
    printf("%02x %02x %02x %02x\n", 
           memory[0], 
           memory[1], 
           memory[2], 
           memory[3]);
}

当针对这个相同的源文件运行时,结果是:。

File Size: 701
23 69 6e 63

注意:23 69 6e 63 ,是指在 " "中的十六进制值。#inc

我修改了内存的类型:char 。 如果你想保持unsigned ,那么请注意,一个32位无符号包含8个nibbles,所以调用printf() 的格式字符串应该是%08x ,以显示每个无符号值

推荐产品

云服务器_QVM_云主机

云服务器_QVM_云主机

便宜云服务器 QVM 以云服务器为核心,提供含云硬盘、云数据库、高防、负载均衡等解决方案为一体的云计算综合服务。
CDN_内容分发网络

CDN_内容分发网络

七牛 CDN 提供稳定快速的网络访问服务。保障您的音视频点播、大文件下载、应用及 Web 加速服务的稳定及连续性。
云存储_对象存储

云存储_对象存储

便宜云服务器对象存储系统 kodo 支持中心和边缘存储,经过多年大规模用户验证已跻身先进技术行列,并广泛应用于海量数据管理的各类场景。
实时音视频通信_RTC

实时音视频通信_RTC

七牛实时音视频云为您提供一站式解决方案,零基础搭建音视频平台,快速支持视频通话、多人会议、互动直播、语音聊天室等多种业务场景。
页面原文内容由 Bret Hasel、user3629249 等提供。便宜云服务器提供翻译支持。
如您不希望该内容被发布至本网站,请发送邮件至:ug#qiniu.com(邮箱中 # 请改为 @)进行申诉,一经确认,我们将立即删除该内容。
http://www.vxiaotou.com