c - sscanf 和 scanset 停止读取十六进制数

标签 c scanf uuid

我尝试验证 UUID v4。我尝试使用 sscanf 执行此操作,如果可以使用 sscanf 完全读取 UUID(= 读取的字符总数 - 36),我认为这是正确的 UUID。我的代码到现在:

#include <stdio.h>

int main()
{
    char uuid[ 37 ] = "da4dd6a0-5d4c-4dc6-a5e3-559a89aff639";
    int a = 0, b = 0, c = 0, d = 0, e = 0, g = 0;
    long long int f = 0;

    printf( "uuid >%s<, variables read: %d \n", uuid, sscanf( uuid, "%8x-%4x-4%3x-%1x%3x-%12llx%n", &a, &b, &c, &d, &e, &f, &g ) );
    printf( " a - %x, b - %x,  c - %x,  d - %x,  e - %x, f - %llx, total number of characters read - %d \n", a, b, c, d, e, f, g );

    return 0;
}
返回以下输出
uuid >da4dd6a0-5d4c-4dc6-a5e3-559a89aff639<, variables read: 6 
 a - da4dd6a0, b - 5d4c,  c - dc6,  d - a,  e - 5e3, f - 559a89aff639, total number of characters read - 36 
到目前为止,一切正常。
现在我想包括,第三个连字符之后的第一个字符需要是 [89ab] 之一。所以我改了%1x%3x%1x[89ab]%3x .但是现在,第一个字符被读取,其余的不再读取。
输出:
uuid >da4dd6a0-5d4c-4dc6-a5e3-559a89aff639<, variables read: 4 
a - da4dd6a0, b - 5d4c,  c - dc6,  d - a,  e - 0, f - 0, total number of characters read - 0 
我错过了什么?语法有什么问题?可以这样读吗?我尝试了扫描集和说明符的几种组合,但没有任何效果。

最佳答案

Now I want to include, that the first character after the third hyphen needs to be one of [89ab]. So I changed %1x%3x to %1x[89ab]%3x


应该是"%1[89ab]%3x"然后保存成2个字符的字符串。然后使用 strtol(..., ..., 16) 将该小字符串转换为十六进制值.

相反,我建议对 universally unique identifier (UUID) 进行两步验证
:
检查语法,然后读取值。
我会避免 "%x"因为它允许前导空格,前导 '+','-'和可选的领先 0x和窄输入。
为了验证,也许是一个简单的代码测试:
#include <ctype.h>
#include <stdio.h>

// byte lengths: 4-2-2-2-6
typedef struct {
  unsigned long time_low;
  unsigned time_mid;
  unsigned time_hi_and_version;
  unsigned clock_seq_hi_and_res_clock_seq_low;
  unsigned long long node;
} uuid_T;

uuid_T* validate_uuid(uuid_T *dest, const char *uuid_source) {
  static const char *uuid_pat = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
  const char *pat = uuid_pat;
  const unsigned char *u = (const unsigned char*) uuid_source;

  while (*u) {
    if ((*pat++ == 'x' && !isxdigit(*u)) || *u != '-') {
      return NULL;
    }
    u++;
  }
  if (*pat) {  // Too short
    return NULL;
  }
  sscanf(uuid_source, "%lx-%x-%x-%x-%llx", &dest->time_low,
      &dest->time_mid, &dest->time_hi_and_version,
      &dest->clock_seq_hi_and_res_clock_seq_low, &dest->node);
  return dest;
}
uunsigned char *u所以isxdigit(*u)仅使用非负值调用,因此避免使用 UB,

关于c - sscanf 和 scanset 停止读取十六进制数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65313958/

相关文章:

c - 在 C 中序列化数据结构

C++ - 获取整数位的大小

c - C语言扫描错误

c - 使用 fscanf : Finding a char in an input

mongodb - Spring Data Entity UUID 在 MongoDB 中存储为旧版 UUID

c - 我的删除有问题

c - 求 c 中 3 个数字的平均值并避免溢出。代码有什么问题吗?

c - C语言获取多个单词不获取\n

ios - 我们在 iOS 上有哪个唯一设备标识符在安装/删除/重新安装应用程序时不会改变

ios - iBeacon 通知数据库