如何在C中将十六进制数读入unsigned int

时间:2009-09-08 22:44:20

标签: c file copying

我想将文本文件中的十六进制数读入无符号整数,以便我可以执行机器指令。它只是一个模拟类型的东西,它查看文本文件内部并根据值及其相应的指令输出寄存器中的新值。

例如,说明如下:

  • 1RXY - >保存寄存器R的值为 内存地址XY
  • 2RXY - >将寄存器R保存为值XY
  • BRXY - >如果xy是,则跳转到寄存器R. 这等等......
  • ARXY - > AND将R值注册为 内存地址XY

文本文件在新行中包含类似的内容。 (在十六进制中)

  • 120F
  • B007
  • 290B

我的问题是将每条指令复制到无符号整数...我该怎么做?

#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]);
}

6 个答案:

答案 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(...)) {
}