读取十六进制数并验证其在C中的位数

时间:2016-07-16 23:59:44

标签: c hex printf scanf

我需要在C中读取带有八位数的十六进制数字,我需要对其进行验证。如果小于8位,则填写“0”。如果它超过八位数,请打印“请插入有效数字”之类的消息。

我正在做这样的事情:

unsigned int number;

printf("\nIntroduzca un número: ");
scanf("%08x", &number);

但是使用“%08x”我可以填写“0”,但我不知道插入的数字是否超过8位并打印错误信息。

我想把它读成一个字符串,但后来我需要对它进行位操作并以十六进制和二进制形式打印结果,所以我不知道将数字读成字符串是否是一个好主意。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

将其作为字符串阅读。检查前2个字节以确保它们没有在开头添加 0x 。使用strlen验证长度。

然后正如@Evert所说,使用strtol将其转换为十六进制值,使用基数16.检查strtol的返回值以验证成功或失败 - 输入的有效十六进制数是否

答案 1 :(得分:2)

很少scanf()是用户输入的最佳选择。最好使用fgets()读取一行,然后使用其他代码来解析字符串。

char buf[100];
while (fgets(buf, sizeof buf, stdin)) {
  // code read the text input into a string, now do something with it.

代码正在查找八个十六进制数字,OP位于右侧轨道scanf("%08x"...。此处不需要0,只需8即可将输入限制为8位数。使用" "跳过任何可选的空格。使用"%n"记录解析的字符数。

  unsigned number = 0;
  int n = 0;
  // If any length (up to 8) hex text was found ...
  // ... and test if `buf[n]` is the end of the string or maybe that 9 digit?
  if (sscanf(buf, "%8x %n", &number, &n) == 1) && buf[n] == '\0') {
    printf("Success :%08x\n", number);
  } else {
    fprintf(stderr, "please insert a valid number\n");
  }
}

如果代码需要确保文本不包含类似"0x123"的引导,则需要做更多工作。各种方法。

使用*scanf()说明符,使用"%*[0123456789abcdefABCDEF]"扫描字符串中的十六进制数字。 *表示不保存,只需扫描。

  int n = 0;
  // If any length (up to 8) hex text was found ...
  // ... and test if `buf[n]` is the end of the string or maybe that 9 digit?
  sscanf(buf, "%*8[0123456789abcdefABCDEF] %n", &n);
  if (n > 0 && buf[n] == '\0') {
    unsigned long number = strtoul(buf, NULL, 16);
    printf("Success :%08lx\n", number);
  } else {
    fprintf(stderr, "please insert a valid number\n");
  }
}

聪明的方法是一起避免*scanf()并将"0x"添加到要解析的字符串中,并仅使用strtol()进行解析。

char buf[100];
while (fgets(&buf[2], sizeof buf - 2, stdin)) {
  char *endptr;
  buf[0] = '0';
  buf[1] = 'x';
  unsigned long number = strtoul(buf, &endptr, 16);
  int length = (int) (endptr - buf);
  if (length < 3 || length > (2 + 8) || *endptr != '\n') {
    fprintf(stderr, "please insert a valid number\n");
  } else {
    printf("Success :%08lx\n", number);
  }
}