我想将文本文件中的十六进制数读入无符号整数,以便我可以执行机器指令。它只是一个模拟类型的东西,它查看文本文件内部并根据值及其相应的指令输出寄存器中的新值。
例如,说明如下:
文本文件在新行中包含类似的内容。 (在十六进制中)
我的问题是将每条指令复制到无符号整数...我该怎么做?
#include <stdio.h>
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]);
}
答案 0 :(得分:5)
你走在正确的轨道上。这是我看到的问题:
fopen()
返回NULL
,您需要退出 - 您正在打印错误消息,但之后仍在继续。i >= 80
时终止,所以你不会读取比你有空间更多的整数。num[i]
的地址(而不是值)传递给fscanf
。fscanf()
两次,这意味着你丢弃了一半的值而没有存储它们。以下是修复这些问题的原因:
#include <stdio.h>
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
}
答案 1 :(得分:5)
您还可以使用函数strtol()。如果使用16的基数,它会将十六进制字符串值转换为int / long。
errno = 0;
my_int = strtol(my_str, NULL, 16);
/* check errno */
编辑:另外注意,各种静态分析工具可能会将atoi()和scanf()等标记为不安全。 atoi已经过时,因为它没有像strtol()那样检查错误。另一方面,scanf()可以执行各种缓冲区溢出,因为它不检查发送到scanf()的类型。例如,你可以给一个指向scanf的短指针,其中读取值实际上是一个很长的....并且繁荣。
答案 2 :(得分:2)
在这种情况下,当您尝试阅读小写字母时,所有输入都是大写十六进制。
要解决此问题,请将%x
更改为%X
。
答案 3 :(得分:2)
你在数组的每个元素中读取两个数字(因此在覆盖它们时会丢失一半。尝试使用
while (i < 80 && fscanf(f,"%x",&num[i]) != EOF)
i++;
为你的循环
修改强>
你也错过了'&amp;'获取数组元素的地址,因此您将随机垃圾指针传递给scanf并可能崩溃。 -Wall选项是你的朋友。
答案 4 :(得分:0)
答案 5 :(得分:0)
您是否希望将每条线(每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(...)) {
}