将超级块读入 C 结构
我有一个磁盘映像,其中包含使用保险丝的标准映像。 Superblock 包含以下内容,我有一个函数 read_superblock(*buf) 返回以下原始数据:
Bytes 0-3: Magic Number (0xC0000112)
4-7: Block Size (1024)
8-11: Total file system size (in blocks)
12-15: FAT length (in blocks)
16-19: Root Directory (block number)
20-1023: NOT USED
我对 C 非常陌生,为了让我开始这个项目,我很好奇将其读入一个简单的方法是什么结构体或一些变量,只需使用 printf 将它们打印到屏幕上即可进行调试。
我最初想做类似以下的事情,认为我可以看到原始数据,但我认为事实并非如此。也没有结构,我试图将其作为字符串读取,这似乎也非常错误。让我从中获取数据。有没有办法让我指定结构并定义每个变量中的字节数?
char *buf;
read_superblock(*buf);
printf("%s", buf);
I have a disk image which contains a standard image using fuse. The Superblock contains the following, and I have a function read_superblock(*buf) that returns the following raw data:
Bytes 0-3: Magic Number (0xC0000112)
4-7: Block Size (1024)
8-11: Total file system size (in blocks)
12-15: FAT length (in blocks)
16-19: Root Directory (block number)
20-1023: NOT USED
I am very new to C and to get me started on this project I am curious what is a simple way to read this into a structure or some variables and simply print them out to the screen using printf for debugging.
I was initially thinking of doing something like the following thinking I could see the raw data, but I think this is not the case. There is also no structure and I am trying to read it in as a string which also seems terribly wrong. for me to grab data out of. Is there a way for me to specify the structure and define the number of bytes in each variable?
char *buf;
read_superblock(*buf);
printf("%s", buf);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,我认为你最好将其读入一个结构中。包含有用数据的字段都是 32 位整数,因此您可以定义如下所示的结构(使用标准头文件
stdint.h
中定义的类型):您可以将该结构强制转换为a
char*
调用read_superblock
时,如下所示:现在要打印数据,您可以进行如下调用:
请注意,您需要了解您的平台的使用此类技术时的字节顺序,因为您正在读取整数数据(即,在读取数据时可能需要交换字节)。您应该能够使用第一个字段中的幻数快速确定这一点。
请注意,通常最好传递这样的结构而不进行强制转换;这使您可以利用编译器的类型检查并消除转换可能隐藏的潜在问题。但是,这需要更改
read_superblock
的实现以将数据直接读取到结构中。这并不困难,可以使用标准 C 运行时函数fread
来完成(假设您的数据位于文件中,正如您的问题所暗示的那样),如下所示:Yes, I think you'd be better off reading this into a structure. The fields containing useful data are all 32-bit integers, so you could define a structure that looks like this (using the types defined in the standard header file
stdint.h
):You can cast the structure to a
char*
when callingread_superblock
, like this:Now to print out your data, you can make a call like the following:
Note that you need to be aware of your platform's endianness when using a technique like this, since you're reading integer data (i.e., you may need to swap bytes when reading your data). You should be able to determine that quickly using the magic number in the first field.
Note that it's usually preferable to pass a structure like this without casting it; this allows you to take advantage of the compiler's type-checking and eliminates potential problems that casting may hide. However, that would entail changing your implementation of
read_superblock
to read data directly into a structure. This is not difficult and can be done using the standard C runtime functionfread
(assuming your data is in a file, as hinted at in your question), like so:这里要添加两件事:
#pragma pack(0)
并在结构定义之后使用#pragma pack()
来执行此操作。ntohs()
和ntohl()
,分别针对 16 位和 32 位值。请注意,它们从网络字节顺序交换为主机字节顺序;如果它们相同(它们不在基于 x86 的平台上),则它们不执行任何操作。您可以使用htons()
和htonl()
从主机字节顺序转到网络字节顺序。但是,由于这些数据来自您的文件系统而不是网络,因此我不知道字节顺序是否是一个问题。通过将您期望的值(例如块大小)与您获得的十六进制值进行比较,应该很容易弄清楚。Two things to add here:
#pragma pack(0)
before the struct definition and#pragma pack()
after it.ntohs()
andntohl()
, for 16- and 32-bit values respectively. Note that these swap from network byte order to host byte order; if these are the same (which they aren't on x86-based platforms), they do nothing. You go from host to network byte order withhtons()
andhtonl()
. However, since this data is coming from your filesystem and not the network, I don't know if endianness is an issue. It should be easy enough to figure out by comparing the values you expect (e.g. the block size) with the values you get, in hex.将数据成功复制到 Emerick 提出的结构后,打印数据并不困难。假设用于保存数据的结构实例名为 SuperBlock_t_Instance。
然后你可以像这样打印它的字段:
It's not difficult to print the data after you successfully copied data into a structure Emerick proposed. Suppose the instance of the structure you use to hold data is named SuperBlock_t_Instance.
Then you can print its fields like this: