Reading a file of hex chars

N

Niv (KP)

I have a file (which I create with a tcl script) which is a fullof
byte data in hex format.
The file is one byte 92 hex chars) per line, but easily changed to
something else.

I want to read this file with a C app, and fill a 2D array (probably
3x3 or 5x5) with data from the file, but so far when i read the byte
data I also get the CR/LF chars.

Also, if the file has non hex chars in any line, I want to discard
that line (e.g address modifier line).

Help please, (C newbie-ish).
 
B

Ben Bacarisse

Niv (KP) said:
I have a file (which I create with a tcl script) which is a fullof
byte data in hex format.
The file is one byte 92 hex chars) per line, but easily changed to
something else.

I want to read this file with a C app, and fill a 2D array (probably
3x3 or 5x5) with data from the file, but so far when i read the byte
data I also get the CR/LF chars.

Also, if the file has non hex chars in any line, I want to discard
that line (e.g address modifier line).

More information is needed! A simple solution would be post an
example file and say what parts you want to read and what parts are to
be ignored.

You also need to say what the base type of the array is and if you
know the dimensions of it in advance. Reading data into a 3x3 char
array and reading 64-bit floating-point data into an array that could
be 3x3x or 5x5 are two very different problems.

To get you started, scanf (and its friends fscanf and sscanf) can read
a hex number with a format of "%x" but the details all depend on
information not given above.
 
N

Niv (KP)

More information is needed!  A simple solution would be post an
example file and say what parts you want to read and what parts are to
be ignored.

You also need to say what the base type of the array is and if you
know the dimensions of it in advance.  Reading data into a 3x3 char
array and reading 64-bit floating-point data into an array that could
be 3x3x or 5x5 are two very different problems.

To get you started, scanf (and its friends fscanf and sscanf) can read
a hex number with a format of "%x" but the details all depend on
information not given above.

OK, The array will hold byte data, 8 bits, so I guess int (or short
int) type.
So if I use scanf/fscanf with %x, I'll have to get two chars at a time
I guess?

Then mult first scanned char by 16 & add 2nd char value? Am I on the
right lines?
 
J

Jens Thoms Toerring

Niv (KP) said:
I have a file (which I create with a tcl script) which is a fullof
byte data in hex format.
The file is one byte 92 hex chars) per line, but easily changed to
something else.

Sorry, this isn't a description that's very easy to understand.
Do you mean that your file consists of lines like this

06d3b72a....

with 92 characters from '0' to '9' and 'a' to 'f' (or 'A' to 'F')
or do you have 184 such characters where each pair makes up one
of 92 1-byte hex numbers between 00 and ff?
I want to read this file with a C app, and fill a 2D array (probably
3x3 or 5x5) with data from the file, but so far when i read the byte
data I also get the CR/LF chars.

If you have lines then they need to end in some end-of-line character
or sequence, otherwise you wouldn't have lines. Just throw that away
after you have read in a line using e.g. fgets().
Also, if the file has non hex chars in any line, I want to discard
that line (e.g address modifier line).

When you have read in a line (and removed the end-of-line marker)
then check each character using e.g. isxdigit() and if that doesn't
succeed for one of the characters throw the line away.

Regards, Jens
 
N

Niv (KP)

Sorry, this isn't a description that's very easy to understand.
 Do you mean that your file consists of lines like this

06d3b72a....

with 92 characters from '0' to '9' and 'a' to 'f' (or 'A' to 'F')
or do you have 184 such characters where each pair makes up one
of 92 1-byte hex numbers between 00 and ff?


If you have lines then they need to end in some end-of-line character
or sequence, otherwise you wouldn't have lines. Just throw that away
after you have read in a line using e.g. fgets().


When you have read in a line (and removed the end-of-line marker)
then check each character using e.g. isxdigit() and if that doesn't
succeed for one of the characters throw the line away.

                               Regards, Jens

Bit of finger trouble typing, should have read:

"The file is one byte (2 hex chars) per line, but easily changed to
something else."
 
B

Ben Bacarisse

Post a file. Everything else just wastes time.


[Best not to quote sigs. Snip the parts you don't comment on and which
you don't need to keep the context.]
OK, The array will hold byte data, 8 bits, so I guess int (or short
int) type.

You can hold byte data in an int, but you can also use char. I'd use
unsigned char or said:
So if I use scanf/fscanf with %x, I'll have to get two chars at a time
I guess?

No. %x reads sequences of characters and converts them to an integer
just like %d reads characters that represent decimal digits and
converts them to an integer.
Then mult first scanned char by 16 & add 2nd char value? Am I on the
right lines?

Post a file! At the least post some of the file. All the problems
will be to do with how to read the sequence and I can't help much
until I know what the file looks like. This fragment:

unsigned int num;
while (scanf("%2x", &num) == 1)
/* put num into the byte array */;

reads two-digit hex numbers so that you can put them somewhere, but
even this may be wrong for your format.
 
J

Jens Thoms Toerring

Niv (KP) said:
Bit of finger trouble typing, should have read:
"The file is one byte (2 hex chars) per line, but easily changed to
something else."

Ah, I see. Then using sscanf() with "%x" is perhaps the simplest
solution after carefully checking a line just read in. Something
like the following should do for a start:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_LINE_LEN 10
#define MAX_BYTES 128

int main( void )
{
FILE *fp;
unsigned char data[ MAX_BYTES ];
char line[ MAX_LINE_LEN ];
unsigned int buf;
size_t count = 0;
size_t len;

if ( ( fp = fopen( "f.dat", "r" ) ) == NULL ) {
fprintf( stderr, "Can't open file\n" );
exit( EXIT_FAILURE );
}

while ( count < MAX_BYTES ) {
if ( fgets( line, MAX_LINE_LEN, fp ) == NULL )
break; /* end of file is reached (or read error) */

/* A valid line must contain two hex digits and a LF (or
EOF must be reached), all other lines are skipped */

if ( ( len = strlen( line ) ) >= 2
&& isxdigit( ( unsigned char ) line[ 0 ] )
&& isxdigit( ( unsigned char ) line[ 1 ] )
&& ( len == 2 || ( len == 3 && line[ 2 ] == '\n' ) ) ) {
sscanf( line, "%x", &buf );
data[ count++ ] = buf;
continue;
}

/* Discard line, taking care of lines longer than MAX_LINE_LEN */

if ( line[ len - 1 ] == '\n' )
continue;

while ( fgets( line, MAX_LINE_LEN, fp ) != NULL
&& line[ strlen( line ) - 1 ] != '\n' )
/* empty */ ;
}

fclose( fp );

/* Now copy from the 'data' array elements to whatever 2D array
you need */

return 0;
}
Regards, Jens
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top