Read In Hex Values (C)
I am currently attempting to read in Hex values from a text file.
There can be multiple lines of Hex's and each line can be as long as needed:
f53d6d0568c7c7ce
1307a7a1c84058
b41af04b24f3eb83ce
Currently, I put together a simple loop to read in the Hex values into an unsigned char line[500]
with fsca开发者_高级运维nf as such:
for(i=0; i < 500; i++)
{
if (fscanf(fp, "%02x", &line[i]) != 1) break;
}
At the current moment, this only reads in the first line. As well, it is definitely not the best approach to just throw in a random 500 there to read.
I was assuming I could use sscanf
with fgets
or something of that nature. But I was unsure if this would be the best approach.
If anyone could help point me in the right direction, I would greatly appreciate it.
You're on the right track with fgets()
and sscanf()
; that will let you size everything appropriately. If your data is really in that format, sscanf()
might be overkill; you could just write a quick conversion loop yourself and save all those variadic function calls.
Note that sscanf is slow (library calls, memory usage, and overkill). Moreover it isway too dangerous (b/c of possible buffer overrun).
You probably would get better results with your own parser. It may show as a bigger source code but it gives you the chance to control and expand your code exactly as needed, without compromising security and speed.
The usual way is to accumulate the hex digits one by one as you read them and build up the corresponding integer:
hexDigit = one letter from "0123456789ABCDEF" remapped to a number within 0-15
accumulating_number= accumulating_number * 16 + hexDigit
Here is a tiny standalone parser as a full example. It accepts lower and upper case and it ignores any non hex character (so you can use space or commas for better readability in the source):
#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;
}
If you give this parser it the following (somehow weird) file content:
ca 53,
FF 00
aa bb cc dd
then the function do_something_with() will output this:
CA53FF00 AABBCCDD
精彩评论