如何从输入文件中分离/解码二进制字符串? (C)

时间:2018-04-30 17:59:02

标签: c visual-studio parsing input binary

我的程序设法逐行读入输入文本文件,现在我正在尝试处理特定部分。输入如下所示:

^Other stuff^
CODE
10001100001000100000000000000000
00000000010000110010000000100000
10101100001001000000000000000000
(End of file after CODE section)

二进制数是一个MIPS指令,可以有任意数量的行(我用3作为例子)。我需要将每个32位线分成6个部分:OpCode,rs,rt,rd,shamt,funct(分别为6,5,5,5,5,6位)。

我已经做过的事情:我的程序已经可以读取输入文本并为每个部分调用正确的函数。以下是上下文的小片段:

char line[64];

int mode = 0; //for parsing sections, 1 = REGISTER, 2 = MEMORY, 3 = CODE

while (fgets(line, sizeof line, filePtr) != NULL) {
    if (strcmp(line, "REGISTERS\n") == 0) {
        mode = 1;
    }

    else if (strcmp(line, "MEMORY\n") == 0) {
        mode = 2;
    }

    else if (strcmp(line, "CODE\n") == 0) {
        mode = 3;
    }

    switch (mode) {
    case 1:
        parseRegisters(line, registers); //this part works
        break;
    case 2:
        parseMemory(line, memory);  //this part works
        break;
    case 3:
        parseCode(line);  //have not started writing this function
        break;
    default:
        break;
    }

所以在本节中,它开始为每个二进制行调用parseCode()。如何编写parseCode()将每一行分成6个部分?然后我需要执行不同的操作,具体取决于部分解码的内容,但我已经涵盖了这些内容。

1 个答案:

答案 0 :(得分:0)

可以使用0将一串零(1)和一些(strtoul)转换为32位数字:

char *end;
uint32_t value = strtoul(line, &end, 2);

您可以使用end确保正确使用整个line。第三个参数指定用于转换的基础。

获得该值后,您可以使用常规位屏蔽逻辑轻松屏蔽该数字的相关部分。这些位实际驻留的位置取决于平台,但假设小端:

#define OPCODE_MASK (0x3FUL <<  0)
#define RS_MASK     (0x1FUL <<  6)
#define RT_MASK     (0x1FUL << 11)
#define RD_MASK     (0x1FUL << 16)
#define SHAMT_MASK  (0x1FUL << 21)
#define FUNCT_MASK  (0x3FUL << 26)

#define GET_OPCODE(X) (((X) & OPCODE_MASK) >>  0)
#define GET_RS(X)     (((X) & RS_MASK)     >>  6)
#define GET_RT(X)     (((X) & RT_MASK)     >> 11)
#define GET_RD(X)     (((X) & RD_MASK)     >> 16)
#define GET_SHAMT(X)  (((X) & SHAMT_MASK)  >> 21)
#define GET_FUNCT(X)  (((X) & FUNCT_MASK)  >> 26)

或者,如果您不介意特定于平台的行为,可以尝试通过具有位字段的结构来解压缩值。

union decode {
    uint32_t code;
    struct {
        uint32_t opcode : 6;
        uint32_t rs     : 5;
        uint32_t rt     : 5;
        uint32_t rd     : 5;
        uint32_t shamt  : 5;
        uint32_t funct  : 6;
    };
};

DEMO