使用scanf从用户输入十六进制指令并将其保存在char中。 (C)

问题描述 投票:1回答:2

所以,我正在构建一个应该修改二进制文件中特定字节数的程序。首先输入二进制文件,然后输入要从中替换十六进制指令的偏移量,然后输入字节本身。

示例:我加载example.exe我指定偏移量0(文件的开头)我指定了十六进制指令:4D FF 33 FD FE文件的前5条指令应该替换为我提供的指令。我使用fwrite进行修改,使用scanf来获取偏移量和十六进制指令,但是,我找不到将它们实际存储为十六进制的方法。 fwrite实际上将4D FF 33 FD FE作为文本写入二进制文件而不是hex。我假设我首先在char中将它们保存错误。我是C的新手,所以我在网上找到的并没有真正帮助。

这是我的代码:

      scanf("%ld",&offset_ed);//get the offset from the user.
      fseek(f, offset_ed, SEEK_SET);
      printf("Specify HEX bytes to be written to the binary:  ");
      scanf("%s\n", &hexes);
      fwrite (hexes , sizeof(char), sizeof(hexes), f);
      fclose (f);

其中hexes是char hexes;

c hex scanf
2个回答
1
投票

您已将hexes作为字符串,因此您需要将它们转换为无符号字符(一个字节),然后才能将它们写入文件。

#include <string.h>
#include <stdio.h>
#define ishexchar(c) (c>='A' && c<='F') || (c>='a' && c<='f')
#define toupper(c) c - 32
#define isupper(c) c>='A' && c<='F'

unsigned char hexconv(const char* str, int size){
    unsigned char ret = 0;
    for(int i=0; i<size; i++){
        if(ishexchar(str[i])){
            char c = (isupper(str[i])) ? str[i] : toupper(str[i]);
            ret = (ret*16) + (c - 'A') + 10;
        }else{
            ret = (ret*16) + (str[i] - '0');
        }
    }
    return ret;
}

int main(){
    printf("%x\n",hexconv("4b", 2));
}

上面的代码可能需要对您的需求进行一些修改,但它可以编译并运行。


3
投票

一般的想法如下。

不要使用scanf(),使用fgets()读取一行用户输入。

错误检查省略(以// **标注)

 char buf[100];   // Use some reasonable upper bound of expected user input.

 puts("prompt for input");
 fgets(buf, sizeof buf, stdin);     // **
 offset_ed = strtol(buf, NULL, 10); // **
 fseek(f, offset_ed, SEEK_SET);     // **

 puts("prompt for input");
 fgets(buf, sizeof buf, stdin);  // **
 size_t byte_count = 0;
 unsigned char hexes[(sizeof buf)/2] = 0;  // place to save the "hex bytes"
 int n = 0;
 unsigned byte; 

现在解析字符串寻找十六进制输入。

 // Use "%n" to save the offset of the scan to later update `p`
 // Robust code would use `strtol()` for its better error handling
 char *p = buf;
 while (sscanf(p, "%x %n", &byte, &n) == 1) {
   if (byte > 0xFF) Handle_OutOfRange();
   hexes[byte_count] = byte;
   p += n;  
 }  

 if (byte_count == 0) Handle_EmptyUserInput();
 if (*p) Handle_ExtraJunkInUserInput();
 fwrite (hexes , byte_count, sizeof hexes[0], f); // **

OP有scanf("%s\n",..."\n"是个问题。 scanf()将阻止,直到用户在预期输入后输入一些非空白区域。避免这样做。

问题可以用scanf()处理,但它很难看。实际上,代码需要使用'\n'等在多个“十六进制”字节之后的某处查找scanf("%*1[^\n]")scanf()不是这里整体编码目标的最佳工具。 scanf()很少是棚屋里最锋利的工具。

© www.soinside.com 2019 - 2024. All rights reserved.