1

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

可以有多行十六进制,每行可以根据需要长:

  f53d6d0568c7c7ce

  1307a7a1c84058

  b41af04b24f3eb83ce

目前,我整理了一个简单的循环,以将十六进制值读入unsigned char line[500]with fscanf ,如下所示:

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

目前,这仅读取第一行。同样,在其中随机放入 500 个进行阅读绝对不是最好的方法。

我假设我可以使用sscanfwithfgets或类似的东西。但我不确定这是否是最好的方法。

如果有人可以帮助我指出正确的方向,我将不胜感激。

4

2 回答 2

3

你在正确的轨道fgets()sscanf(); 这将使您可以适当地调整所有内容。如果您的数据确实是那种格式,那sscanf()可能是矫枉过正;您可以自己编写一个快速转换循环并保存所有这些可变参数函数调用。

于 2009-10-16T21:45:29.573 回答
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
于 2011-01-04T14:17:14.307 回答