如何在C中将hex数读入无符号整数
我想将文本文件中的hex数读入无符号整数,以便我可以执行机器指令。 它只是一个模拟类型的东西,它查看文本文件内部并根据值及其相应的指令输出寄存器中的新值。
例如,说明将是:
- 1RXY – >将寄存器R保存为存储器地址XY中的值
- 2RXY – >将寄存器R保存为XY值
- BRXY – >跳转到寄存器R,如果xy是这个等等。
- ARXY – > AND在内存地址XY处注册R值
文本文件在新行中包含类似的内容。 (在hex中)
- 120F
- B007
- 290B
我的问题是将每个单独的指令复制到无符号整数…我该怎么做?
#include int main(){ FILE *f; unsigned int num[80]; f=fopen("values.txt","r"); if (f==NULL){ printf("file doesnt exist?!"); } int i=0; while (fscanf(f,"%x",num[i]) != EOF){ fscanf(f,"%x",num[i]); i++; } fclose(f); printf("%x",num[0]); }
你走在正确的轨道上。 这是我看到的问题:
- 如果
fopen()
返回NULL
则需要退出 – 您正在打印错误消息但随后继续。 - 如果
i >= 80
,你的循环应该终止,所以你不会读取比你有空间更多的整数。 - 您需要将
num[i]
的地址而不是值传递给fscanf
。 - 你在循环中调用
fscanf()
两次,这意味着你丢弃了一半的值而没有存储它们。
以下是修复这些问题的样子:
#include int main() { FILE *f; unsigned int num[80]; int i=0; int rv; int num_values; f=fopen("values.txt","r"); if (f==NULL){ printf("file doesnt exist?!\n"); return 1; } while (i < 80) { rv = fscanf(f, "%x", &num[i]); if (rv != 1) break; i++; } fclose(f); num_values = i; if (i >= 80) { printf("Warning: Stopped reading input due to input too long.\n"); } else if (rv != EOF) { printf("Warning: Stopped reading input due to bad value.\n"); } else { printf("Reached end of input.\n"); } printf("Successfully read %d values:\n", num_values); for (i = 0; i < num_values; i++) { printf("\t%x\n", num[i]); } return 0 }
您还可以使用函数strtol()。 如果使用16的基数,它会将hex字符串值转换为int / long。
errno = 0; my_int = strtol(my_str, NULL, 16); /* check errno */
编辑:另外注意,各种静态分析工具可能会将atoi()和scanf()等标记为不安全。 atoi已经过时,因为它没有像strtol()那样检查错误。 另一方面,scanf()可以执行各种缓冲区溢出,因为它不检查发送到scanf()的类型。 例如,你可以给一个指向scanf的短指针,其中读取值实际上是一个很长的….并且繁荣。
你正在读取数组的每个元素中的两个数字(因此当你覆盖它们时,你会失去一半数。请尝试使用
while (i < 80 && fscanf(f,"%x",&num[i]) != EOF) i++;
为你的循环
编辑
你也错过了'&'来获取数组元素的地址,因此你将随机垃圾指针传递给scanf并且可能会崩溃。 -Wall选项是你的朋友。
在这种情况下,当您尝试读取小写十六 进制时,所有输入都是大写十六 进制 。
要修复它,请将%x
更改为%X
。
你想要每个线(每4个字符长)分成4个不同的数组元素吗? 如果你这样做,我会试试这个:
/* read the line */ /* fgets(buf, ...) */ /* check it's correct, mind the '\n' */ /* ... strlen ... isxdigit ... */ /* put each separate input digit in a separate array member */ num[i++] = convert_xdigit_to_int(buf[j++]);
函数convert_xdigit_to_int()只是将’0’(字符)转换为0(一个int),’1’转换为1,’2’转换为2,……’9’转换为9,’a’或’A’到10,……
当然,伪代码在循环内部执行,直到文件用完或数组被填满。 也许把fgets()作为一段时间的条件(…)
while(/*there is space in the array && */ fgets(...)) { }