【问题标题】:Unsuccessfully using sscanf to read in hexadecimal value使用 sscanf 读取十六进制值失败
【发布时间】:2012-04-29 23:00:11
【问题描述】:

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

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

如您所见,我将十六进制字符串传递给函数,将它们读入令牌并使用 sscanf() 将字符串版本的十六进制值转换为无符号整数。字符串标记始终以“0x”、“0X”、“Ox”或“OX”开头。这样做的原因是用户在输入值时将无法区分 0 或 O(vi 将它们显示为相同的图形)。如果我通过它“0x00EE”得到的结果是:

token: 0x00EE
error: 0

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

maskval = strtol(token, NULL, 16);

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

有什么想法吗?

【问题讨论】:

  • 在我的 ViM 中,0 有一个点,而O 没有!
  • 不应该是char token[256];???
  • 另外,%x 也可以读取0x 部分,所以你不需要写token+2

标签: c hex scanf


【解决方案1】:

这里有一个错误:

char *token[256];

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

你的意思是:

char token[256];

这里应该有很多编译器警告。

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

您可以手动去除不合格的前缀。假设你 always 有 2 个字符的前缀,然后 可能 有一个,你可以这样做:

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

【讨论】:

  • 好答案!必须在您的解决方案中修复一些问题,但它现在可以工作了!必须将 while(isxdigit(*number)) 更改为 while(!isxdigit(*number)) 和 if(sscanf) 语句以将 sscanf 评估为 1。
猜你喜欢
  • 2019-09-19
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
相关资源
最近更新 更多