请注意, sscanf 很慢(库调用、内存使用和过度杀伤)。而且它太危险了(可能的缓冲区溢出的b / c)。
使用自己的解析器可能会得到更好的结果。它可能显示为更大的源代码,但它使您有机会完全根据需要控制和扩展代码,而不会影响安全性和速度。
通常的方法是在读取十六进制数字时将它们一一累加并建立相应的整数:
hexDigit = one letter from "0123456789ABCDEF" remapped to a number within 0-15
accumulating_number= accumulating_number * 16 + hexDigit
这是一个小型独立解析器作为完整示例。它接受小写和大写,并忽略任何非十六进制字符(因此您可以使用空格或逗号来提高源代码的可读性):
#include <stdio.h>
#define SPLIT_CHAR_SIZE 8 // size of the hex numbers to parse (eg. 6 for RGB colors)
void do_something_with(unsigned int n)
{
printf("%08X ",n);
}
int main(int argc, char** argv)
{
FILE* fp= (argc!=2) ? stdin : fopen(argv[1],"r");
if(!fp) { fprintf(stderr,"Usage: %s fileToRead\n", argv[0]); return(-1); }
unsigned int i=0, accumulator=0;
char c;
while(!feof(fp)) // you could parse a c-string via fscanf() to handle other file contents
{
c= fgetc(fp);
// The "<<4" gives room for 4 more bits, aka a nibble, aka one hex digit, aka a number within [0,15]
if(c>='0' && c<='9')
accumulator= (accumulator<<4) | (c - '0');
else if(c>='a' && c<='f') // lower case
accumulator= (accumulator<<4) | (c - 'a' + 10);
else if(c>='A' && c<='F') // upper case
accumulator= (accumulator<<4) | (c - 'A' + 10);
else
continue; // skip all other (invalid) characters
// When you want to parse more than one hex number you can use something like this:
if(++i % SPLIT_CHAR_SIZE == 0)
{
do_something_with(accumulator);
accumulator= 0; // do not forget this
}
}
printf("\n");
return 0;
}
如果你给这个解析器以下(有点奇怪)文件内容:
ca 53,
FF 00
aa bb cc dd
然后函数 do_something_with() 将输出:
CA53FF00 AABBCCDD