使用sscanf未能成功读取十六进制值

hal*_*exh 3 c hex scanf

这是我的代码的简短版本:

char token[256];
unsigned int maskval = 0;

//Token gets read in here.

printf("token: %s\n", token);

if (sscanf(token + 2, "%x", &maskval) == 1) {
     //do stuff
} else {
     printf("error: %d, %x\n", maskval, maskval);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我正在将十六进制字符串传递给函数,将它们读取为令牌,然后使用sscanf()将十六进制值的字符串版本转换为无符号int。字符串令牌始终以“ 0x”,“ 0X”,“ Ox”或“ OX”开头。原因是因为用户在输入值时将无法分辨0或O之间的差异(vi用相同的图形方式显示它们)。如果将其传递为“ 0x00EE”,则得到的结果是:

token: 0x00EE
error: 0
Run Code Online (Sandbox Code Playgroud)

我相信的问题是,我是按照“ 0x00EE”还是“ OxOOEE”(零与大写o)的方式传递它。两者在vi中看起来都相同,并且我不确定在这种情况下对它们的处理是否不同。希望我只是做一些我忽略了的简单愚蠢的事情(通常是这种情况)。另外,我尝试使用

maskval = strtol(token, NULL, 16);
Run Code Online (Sandbox Code Playgroud)

而不是sscanf()但我得到的结果完全相同。

有任何想法吗?

unw*_*ind 5

这是一个错误:

char *token[256];
Run Code Online (Sandbox Code Playgroud)

这是指向字符(char *)的256个指针的数组,而不是字符的数组。

你的意思是:

char token[256];
Run Code Online (Sandbox Code Playgroud)

因此,应该有很多编译器警告。

试图解析从字符串开头的东西是不是一个有效的十六进制数字当然会失败,对于一个十六进制值sscanf()strtoul()。您几乎听起来好像在认为标准函数应该考虑'O'为十六进制,只是因为它看起来像数字0。那不是他们的设计方式,我认为这是幸运的。:)您可能想研究更改字体。

您可以手动删除不一致的前缀。假设您始终使用2个字符的前缀,然后可能使用1 个字符,则可以执行以下操作:

const char *number = token + 2;

while(!isxdigit(*number))
  number++;
/* Now number will point at the first hexadecimal
   digit in token, or '\0' if none were found.
*/
if(sscanf(number, "%x", &maskval) == 1)
  printf("success, got %x\n", maskval);
else
  printf("failed to parse '%s' as hexadecimal number\n", number);
Run Code Online (Sandbox Code Playgroud)