4

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

例如,说明将是:

  • 1RXY -> 将寄存器 R 的值保存在内存地址 XY 中
  • 2RXY -> 用值 XY 保存寄存器 R
  • 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]);
}
4

5 回答 5

7

你在正确的轨道上。这是我看到的问题:

  • fopen()如果返回,您需要退出NULL- 您正在打印一条错误消息,然后继续。
  • 你的循环应该终止 if 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
}
于 2009-09-08T23:11:41.990 回答
5

您还可以使用函数 strtol()。如果您使用 16 为基数,它会将您的十六进制字符串值转换为 int/long。

errno = 0;
my_int = strtol(my_str, NULL, 16);
/* check errno */

编辑:另一个注意事项,各种静态分析工具可能会将 atoi() 和 scanf() 之类的东西标记为不安全。atoi 已过时,因为它不像 strtol() 那样检查错误。另一方面,scanf() 可以进行各种缓冲区溢出,因为它不检查发送到 scanf() 的类型。例如,您可以给一个指向 scanf 的 short 的指针,其中读取的值实际上是 long ......并且繁荣。

于 2009-09-08T23:15:15.120 回答
2

在这种情况下,当您尝试读取小写十六进制时,您的所有输入都是大写十六进制。

要修复它,请更改%x%X.

于 2009-09-08T22:59:00.220 回答
2

您正在将两个数字读入数组的每个元素中(因此在覆盖它们时会丢失其中的一半。尝试仅使用

while (i < 80 && fscanf(f,"%x",&num[i]) != EOF)
    i++;

为你的循环

编辑

您还缺少“&”来获取数组元素的地址,因此您将随机垃圾指针传递给 scanf 并且可能会崩溃。-Wall 选项是您的朋友。

于 2009-09-08T23:01:06.223 回答
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(整数)、“1”转换为 1、“2”转换为 2、...“9”转换为 9、“a”或“A”到 10,...

当然,该伪代码位于一个循环内,该循环一直执行到文件用完或数组被填满。也许将 fgets() 作为条件一段时间(...)

while(/*there is space in the array && */ fgets(...)) {
}
于 2009-09-08T23:10:06.580 回答