简体   繁体   English

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

[英]Use scanf to take hex instructions input from the user and save them in char. (C)

So, I am building a program that should modify a specific number of bytes in a binary. 因此,我正在构建一个程序,该程序应修改二进制文件中特定数量的字节。 You first input the binary, then the offset from which point you want the hex instructions to be replaced and then the bytes themselves. 首先输入二进制,然后输入要替换十六进制指令的偏移量,然后输入字节本身。

Example: I load example.exe I specify offset 0 (beginning of the file) I specify hex instructions: 4D FF 33 FD FE The first 5 instructions of the file should be replaced with the ones I provided. 示例:我加载example.exe,我指定了偏移量0 (文件的开头),我指定了十六进制指令: 4D FF 33 FD FE文件的前5条指令应替换为我提供的指令。 I use fwrite to do the modifications and scanf to get the offset and the hex instructions, however, I can't find a way to actually store them as hex. 我使用fwrite进行修改,使用scanf获取偏移量和十六进制指令,但是,我找不到实际将它们存储为十六进制的方法。 The fwrite actually writes 4D FF 33 FD FE as text inside the binary file instead of hex. fwrite实际上将4D FF 33 FD FE作为文本而不是十六进制写入二进制文件中。 I assume I save them wrong in the char in the first place. 我想我首先将错误保存在char中。 I am new to C, so what I found online didn't really help. 我是C语言的新手,所以我在网上发现的内容并没有真正帮助。

Here's my code: 这是我的代码:

      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);

Where hexes is a char hexes; 十六进制为char十六进制;

General idea below. 总体思路如下。

Do not use scanf() , Use fgets() for reading a line of user input. 不要使用scanf() ,而应使用fgets()读取一行用户输入。

Error checking omitted (noted with // **) 省略错误检查(以// **表示)

 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; 

Now parse the string looking for hex input. 现在解析字符串以查找十六进制输入。

 // 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 had scanf("%s\\n",... . The "\\n" is a problem. scanf() will block until the user entered some non-white-space after the expected input. Avoid that. OP具有scanf("%s\\n",... "\\n"是一个问题scanf()会阻塞,直到用户在期望的输入之后输入了一些非空白为止。请避免这种情况。

The problem can be handled with scanf() , yet it is ugly. 这个问题可以scanf()处理,但是很丑陋。 Effectively, code needs to look for the '\\n' somewhere after multiple "hex" bytes using scanf("%*1[^\\n]") or the like. 有效地,代码需要使用scanf("%*1[^\\n]")等在多个“十六进制”字节之后'\\n'某个位置查找'\\n' scanf() is not the best tool for the overall coding goal here. scanf()并不是实现总体编码目标的最佳工具。 scanf() is rarely the sharpest tool in the shed. scanf()很少是棚中最犀利的工具。

You have got the hexes as a string so you need to convert each of them to unsigned chars(a byte) before you can write them to a file. 您已将十六进制作为字符串获取,因此需要先将它们转换为无符号字符(一个字节),然后才能将它们写入文件。

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

The code above might need some modification for your needs but it compiles and works. 上面的代码可能需要根据您的需要进行一些修改,但可以编译并运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM