【问题标题】:Converting hex digits to decimal for comparison (C)将十六进制数字转换为十进制以进行比较 (C)
【发布时间】:2019-07-24 13:17:19
【问题描述】:

我正在尝试制作一个程序来确定是否正确创建了一个 intel hex 文件,而我用来生成它们的一个程序没有正确生成一个,所以我要制作一个。

到目前为止,我可以从目标文件中读取一行,但是在将十六进制数从字符串转换为要比较的数字时遇到问题。这是我令人不安的sn-p:

//hx=opened file handle
unsigned char hexv,hexsz,hexcs;
while ((line=getline(&hexstring,&buffer,hx))> -1){
      //Trying to convert hexadecimal character in byte 7 and 8 of string to number
      //Hexsz must contain actual number representing number of hex digits to process
      sprintf(hexsz,"%02x",hexstring[7]);
      //Checksum = 0
      hexcs=0;
      for (hexc=0;hexc<(hexsz*2);hexc+=2){
        //Add next hexadecimal number to checksum
        sprintf(hexv,"%02x",hexstring[9+hexc]);
        hexcs+=hexv;
      }
      //Check checksum with stored checksum
      sprintf(hexv,"%02x",hexstring[9+hexc]);
      if (hexcs != hexv){
        printf("HEX checksum error!\n");
      }
}

这些 sprintf 出了点问题,我想不通。

我唯一知道的就是执行以下操作:

  1. 分配一个临时字符*
  2. 字符串将十六进制值复制到该字符*
  3. 在该字符上使用 strtol

但是没有更简单的方法吗?

我尝试使用 strtol(startaddress,endaddress,16) 进行转换,但程序无法识别。它期望 endaddress 为 NULL。

那么将大字符串中的两字节字符串转换为十六进制更简单的方法是什么?

例如,如果我的字符串是

:10007B00AB83AD8290015C938D828B83F531EF85E1

我想从中转换值 7B,最简单的方法是什么?

【问题讨论】:

  • 为什么你不能在整个十六进制字符串上使用strtol,或者将一对数字提取到一个临时字符串中并在上面使用strtol?你没有清楚地表明你对strtol的使用。

标签: c string numbers hex decimal


【解决方案1】:

将大字符串中的两字节字符串转换为十六进制的简单方法?

隔离两个字符并转换。

//               012345678 
const char *s = ":10007B00AB83AD8290015C938D828B83F531EF85E1";
int n = 5;

unsigned value;
if (sscanf(s + n, "%2x", &value) == 1) {
  printf("Value at %.2s: %02X\n", s+n, value);
} else {
  puts("Fail");
}

或

// Form a 3-char string such as '7', 'B', '\0'
const char substring[3] = { s[n], s[n+1] };
char *endptr;
long value = strtol(substring, &endptr, 16);
if (endptr > substring) {
  printf("Value at %s: %02X\n", substring, value);
} else {
  puts("Fail");
}

strtol(startaddress,endaddress,16) 是 strtol() 的错误用法。 endptr 是指针的地址,而不仅仅是结束地址。

long int strtol(const char * restrict nptr, char ** restrict endptr, int base);

“它期望 endaddress 为 NULL。” --> 在这里传递NULL 是可以的,但是代码缺少确定转换成功的信息。相反,传递char * 的地址,如上所述。然后测试是否发生了转换。


在不知道s[n] 不是空字符的情况下,Pedantic 代码不会在{ s[n], s[n+1] }; 中使用s[n+1]。但我希望循环已经检查过了。

const char *s = ":10007B00AB83AD8290015C938D828B83F531EF85E1";

if (s[0] == ':') {
  unsigned n = 1;
  while (s[n] && s[n+1]) {
    const char substring[3] = { s[n], s[n+1] };
    ... 
    n += 2;
  }
  ...

`

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-31
    • 2013-07-20
    • 2012-06-17
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多