sscanfは遅いことに注意してください(ライブラリ呼び出し、メモリ使用量、および過剰キル)。さらに、それは危険すぎます(バッファオーバーランの可能性のb / c)。
おそらく、独自のパーサーを使用すると、より良い結果が得られます。より大きなソースコードとして表示される場合がありますが、セキュリティと速度を損なうことなく、必要に応じてコードを正確に制御および拡張する機会が得られます。
通常の方法は、16進数を読みながら、1つずつ累積し、対応する整数を作成することです。
hexDigit = one letter from "0123456789ABCDEF" remapped to a number within 0-15
accumulating_number= accumulating_number * 16 + hexDigit
これは、完全な例としての小さなスタンドアロンパーサーです。小文字と大文字を受け入れ、16進以外の文字を無視します(したがって、ソースで読みやすくするためにスペースまたはコンマを使用できます)。
#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