如何从 C 文件中读取二进制输入
How to read binary inputs from a file in C
我需要做的是从文件中读取二进制输入。输入例如 (binary dump),
00000000 00001010 00000100 00000001 10000101 00000001 00101100 00001000 00111000 00000011 10010011 00000101
我做的是,
char* filename = vargs[1];
BYTE buffer;
FILE *file_ptr = fopen(filename,"rb");
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
for (int i = 0; i < file_length; i++)
{
fread(&buffer, 1, 1, file_ptr); // read 1 byte
printf("%d ", (int)buffer);
}
但这里的问题是,我需要以某种方式划分那些二进制输入,以便我可以将其用作命令(例如输入中的 101 是将两个数字相加)
但是当我 运行 使用我编写的代码的程序时,这为我提供了如下输出:
0 0 10 4 1 133 1 44 8 56 3 147 6
以ASCII码显示。
如何将输入读取为二进制数字,而不是 ASCII 数字?
输入应该这样使用:
0 # Padding for the whole file!
0000|0000 # Function 0 with 0 arguments
00000101|00|000|01|000 # MOVE the value 5 to register 0 (000 is MOV function)
00000011|00|001|01|000 # MOVE the value 3 to register 1
000|01|001|01|100 # ADD registers 0 and 1 (100 is ADD function)
000|01|0000011|10|000 # MOVE register 0 to 0x03
0000011|10|010 # POP the value at 0x03
011 # Return from the function
00000110 # 6 instructions in this function
我正在尝试实现某种类似于汇编语言的命令
有人可以帮我解决这个问题吗?
谢谢!
您需要了解数据及其表示之间的区别。您正在正确读取二进制数据。打印数据时,printf()
给出二进制数据的十进制表示。请注意,二进制的 00001010
与十进制的 10
相同,二进制的 00000100
与十进制的 4
相同。如果将每个位序列转换为其十进制值,您将看到输出是完全正确的。您似乎混淆了数据的表示,因为它是 output 与数据在内存中的读取和存储方式。这是两个截然不同的东西。
解决问题的下一步是学习按位运算符:|
、&
、~
、>>
和 <<
。然后使用适当的运算符组合从位流中提取您需要的数据。
您使用的格式不能被一个字节整除,因此您需要将您的位读入循环缓冲区并使用状态机对其进行解析。
阅读"in binary" 或"in text" 完全相同,唯一不同的是您对数据的解释。在您的示例中,您正在读取一个字节,并且正在打印该字节的十进制值。但是你想打印那个字符的位,为此你只需要使用 C 的二元运算符。
例如:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
struct binary_circle_buffer {
size_t i;
unsigned char buffer;
};
bool read_bit(struct binary_circle_buffer *bcn, FILE *file, bool *bit) {
if (bcn->i == CHAR_BIT) {
size_t ret = fread(&bcn->buffer, sizeof bcn->buffer, 1, file);
if (!ret) {
return false;
}
bcn->i = 0;
}
*bit = bcn->buffer & ((unsigned char)1 << bcn->i++); // maybe wrong order you should test yourself
// *bit = bcn->buffer & (((unsigned char)UCHAR_MAX / 2 + 1) >> bcn->i++);
return true;
}
int main(void)
{
struct binary_circle_buffer bcn = { .i = CHAR_BIT };
FILE *file = stdin; // replace by your file
bool bit;
size_t i = 0;
while (read_bit(&bcn, file, &bit)) {
// here you must code your state machine to parse instruction gl & hf
printf(bit ? "1" : "0");
if (++i >= 7) {
i = 0;
printf(" ");
}
}
}
帮你再多就难了,你基本上是在请求帮助编写一个虚拟机...
我需要做的是从文件中读取二进制输入。输入例如 (binary dump),
00000000 00001010 00000100 00000001 10000101 00000001 00101100 00001000 00111000 00000011 10010011 00000101
我做的是,
char* filename = vargs[1];
BYTE buffer;
FILE *file_ptr = fopen(filename,"rb");
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
for (int i = 0; i < file_length; i++)
{
fread(&buffer, 1, 1, file_ptr); // read 1 byte
printf("%d ", (int)buffer);
}
但这里的问题是,我需要以某种方式划分那些二进制输入,以便我可以将其用作命令(例如输入中的 101 是将两个数字相加)
但是当我 运行 使用我编写的代码的程序时,这为我提供了如下输出:
0 0 10 4 1 133 1 44 8 56 3 147 6
以ASCII码显示。
如何将输入读取为二进制数字,而不是 ASCII 数字?
输入应该这样使用:
0 # Padding for the whole file!
0000|0000 # Function 0 with 0 arguments
00000101|00|000|01|000 # MOVE the value 5 to register 0 (000 is MOV function)
00000011|00|001|01|000 # MOVE the value 3 to register 1
000|01|001|01|100 # ADD registers 0 and 1 (100 is ADD function)
000|01|0000011|10|000 # MOVE register 0 to 0x03
0000011|10|010 # POP the value at 0x03
011 # Return from the function
00000110 # 6 instructions in this function
我正在尝试实现某种类似于汇编语言的命令
有人可以帮我解决这个问题吗?
谢谢!
您需要了解数据及其表示之间的区别。您正在正确读取二进制数据。打印数据时,printf()
给出二进制数据的十进制表示。请注意,二进制的 00001010
与十进制的 10
相同,二进制的 00000100
与十进制的 4
相同。如果将每个位序列转换为其十进制值,您将看到输出是完全正确的。您似乎混淆了数据的表示,因为它是 output 与数据在内存中的读取和存储方式。这是两个截然不同的东西。
解决问题的下一步是学习按位运算符:|
、&
、~
、>>
和 <<
。然后使用适当的运算符组合从位流中提取您需要的数据。
您使用的格式不能被一个字节整除,因此您需要将您的位读入循环缓冲区并使用状态机对其进行解析。
阅读"in binary" 或"in text" 完全相同,唯一不同的是您对数据的解释。在您的示例中,您正在读取一个字节,并且正在打印该字节的十进制值。但是你想打印那个字符的位,为此你只需要使用 C 的二元运算符。
例如:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
struct binary_circle_buffer {
size_t i;
unsigned char buffer;
};
bool read_bit(struct binary_circle_buffer *bcn, FILE *file, bool *bit) {
if (bcn->i == CHAR_BIT) {
size_t ret = fread(&bcn->buffer, sizeof bcn->buffer, 1, file);
if (!ret) {
return false;
}
bcn->i = 0;
}
*bit = bcn->buffer & ((unsigned char)1 << bcn->i++); // maybe wrong order you should test yourself
// *bit = bcn->buffer & (((unsigned char)UCHAR_MAX / 2 + 1) >> bcn->i++);
return true;
}
int main(void)
{
struct binary_circle_buffer bcn = { .i = CHAR_BIT };
FILE *file = stdin; // replace by your file
bool bit;
size_t i = 0;
while (read_bit(&bcn, file, &bit)) {
// here you must code your state machine to parse instruction gl & hf
printf(bit ? "1" : "0");
if (++i >= 7) {
i = 0;
printf(" ");
}
}
}
帮你再多就难了,你基本上是在请求帮助编写一个虚拟机...