使用sscanf

时间:2017-02-27 07:00:22

标签: c scanf

我将收到格式为“%04hx%04hx”的命令参数字符串。示例命令参数字符串是“09EC 000A”。

我需要检查数据格式是否有效。我试图用以下格式字符串

检查参数字符串是否有效

“%[0123456789abcdefABCDEF] s”。即使十六进制数和前导空格之间存在多个空格,此格式也可以使用。

是否可以检查命令参数字符串是否只有两个4位十六进制数字,它们之间是否有sscanf?

马努

2 个答案:

答案 0 :(得分:1)

  

是否可以检查命令参数字符串是否只有两个4位十六进制数字,它们之间是否有sscanf?

是的,检查每个字符并使用"%n"保存字符扫描计数。

  // notice no 's' at the end
  #define HEX1 "%*1[0123456789abcdefABCDEF]"
  // the '*' directs sscanf() to not save the result.
  #define SPC1 "%*1[ ]"

  char *sample = "09EC 000A";
  int n = 0;
  sscanf(sample, HEX1 HEX1 HEX1 HEX1 SPC1 HEX1 HEX1 HEX1 HEX1 "%n", &n);
  if (n && sample[n] == 0) {
    puts("Success");
  } else {
    puts("Fail");
  }

或者可以使用sscanf()的返回值并使用哨兵检测尾随字符。

  char hex[2][5] = { 0 };
  char sentinel;
  #define HEX "%1[0123456789abcdefABCDEF]"
  //#define SPC1 "%*1[ ]"
  if (8 == sscanf(sample, HEX HEX HEX HEX SPC1 HEX HEX HEX HEX "%c",
      &hex[0][0], &hex[0][1], &hex[0][2], &hex[0][3],
      &hex[1][0], &hex[1][1], &hex[1][2], &hex[1][3],
      &sentinel)) {
    printf("Success %s %s\n", hex[0], hex[1]);
  } else {
    puts("Fail");
  }

或者可能是一些不那么冗长的东西

  #define HEX4 "%4[0123456789abcdefABCDEF]"
  sscanf(sample, HEX4 SPC1 HEX4 "%n", hex[0], hex[1], &n);
  if (n == 9 && sample[n] == 0) {
    printf("Success %s %s\n", hex[0], hex[1]);
  } else {
    puts("Fail");
  }

直接使用"%x"允许可选地引导空格字符。可以使用"%n"来检测。然而,"%x"允许"0x12""+123""-123",但不会被以下内容拒之门外。

  int m[4] = { 0 };
  unsigned cmd[2];
  sscanf(sample, " %n%x%n" SPC1 " %n%x%n",
      &m[0], &cmd[0], &m[1],
      &m[2], &cmd[1], &m[3]);
  if (m[0] == 0 && m[1] == 4 && m[2] == 5 && m[3] == 9 && sample[m[3]] == 0) {
    printf("Success %04x %04x\n", cmd[0], cmd[1]);
  } else {
    puts("Fail");
  }

许多可能性。

答案 1 :(得分:0)

sscanf可能不会轻易做到这一点。使用正则表达式或编写自己的验证函数:

#include <ctype.h>
int is_valid (const char *s)
{
    int i = 0;
    for(; i < 4; i++) if (!isxdigit((unsigned char)s[i])) return 0;
    /* change the next line to (s[i++]!=' ') if wanted */
    if (!isspace((unsigned char)s[i++])) return 0; 
    for(; i < 9; i++) if (!isxdigit((unsigned char)s[i])) return 0;
    return 1;
}