如何使用sscanf进行更长的字符串分析

时间:2018-05-24 09:43:50

标签: c string

我刚刚找到了一个将mac地址字符串转换为如下数组的解决方案:

#include <stdio.h>
int main()
{

char mac[] = "ff-13-a9-1f-b0-88";

unsigned char a[6];

sscanf(mac, "%x-%x-%x-%x-%x-%x", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]);

printf("%x,%x", *a, *(a+1));

}

这段代码可以正常工作,符合我的需求。但是如果我想将像ff-13-a9-1f-b0-88...(REPEAT 100 TIMES)...-ff-00这样的长字符串转换为char数组怎么办?

在代码中反复写%x-%x既不方便也不优雅。

我确实考虑将memcpy与循环一起使用,但我不能复制半个字节(将0x0f,0x0f转换为0xff),对吧?

2 个答案:

答案 0 :(得分:1)

逐个阅读,最后使用%n来获取到目前为止消耗的字符数。即。

char *position = mac;
char separator;
int consumed = 0;

while (1) {
    int converted = sscanf(position, "%x%c%n", &one_number, &separator, &consumed);
    if (converted == 2) {
        if (separator == '-') {
            position += consumed;
        }
        else {
            // malformed string, separator wasn't -
        }
    }
    else if (converted == 1) {
        // last number
    }
    else {
        // none converted, scanf error. 
    }
}

答案 1 :(得分:0)

您不需要memcpy,您可以指定值来构建这样的字节。

byte_value = lower_nibble + (higher_nibble<<4);

您按原样使用lower_nibble,但将higher_nibble 4个位置移动到0xf0(或任何值)。

在循环中使用,您可以移动当前字节值,然后添加当前半字节(半字节),然后在达到非十六进制数字时重置它

unsigned int byte_value=0;
char *pos
for(pos=mac;*pos!='\0';pos++)
  {
  if(isdigit(*pos))
    {
    byte_value <<= 4;
    byte_value += *pos-'0';
    }
  else if(isxdigit(*pos))
    {
    byte_value <<= 4;
    byte_value += tolower(*pos)-'a'+10;
    }
  else
    {
    printf("Byte is %x\n",byte_value);
    byte_value=0;
    }
  }
printf("Byte is %x\n",byte_value);