读入十六进制值(C)

时间:2009-10-16 21:42:39

标签: c hex io scanf

我目前正在尝试从文本文件中读取十六进制值。

可以有多行Hex,每行可以根据需要:

  f53d6d0568c7c7ce

  1307a7a1c84058

  b41af04b24f3eb83ce

目前,我将一个简单的循环组合在一起,将Hex值读入unsigned char line[500]并使用fscanf:

  for(i=0; i < 500; i++)
  {
        if (fscanf(fp, "%02x", &line[i]) != 1) break;
  }

目前,这只是在第一行读取。同样,它绝对不是最好的方法,只需要随机输入500即可。

我假设我可以sscanf使用fgets或者那种性质的东西。但我不确定这是否是最佳方法。

如果有人能帮助我指出正确的方向,我将非常感激。

2 个答案:

答案 0 :(得分:3)

您与fgets()sscanf()走在正确的轨道上;这将让你适当地调整大小。如果您的数据确实采用该格式,则sscanf()可能过度;你可以自己编写一个快速转换循环并保存所有那些可变函数调用。

答案 1 :(得分:3)

请注意,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