Streaming Hex Values

I have a data file with hex values representing a byte of data per two hex characters. I have to stream in this data, and I'm currently streaming this data from the file and putting the result, line by line, into a string:

1
2
3
4
5
6
7
8
9
string line;
ifstream data("file.txt");
if(data.is_open())
  {
    while(data.good())
      {
        getline(data,line);
      }
  }


Let's say a given line is "0123456789abcdef". I would like to take this string, break it up, and store the hex values as characters. Essentially, the same result as doing this:

1
2
3
4
5
6
7
8
9
10
11
12
char a;
char b;
char c[6];

a = 0x01;
b = 0x23;
c[0] = 0x45;
c[1] = 0x67;
c[2] = 0x89;
c[3] = 0xab;
c[4] = 0xcd;
c[5] = 0xef;


I need some advice as to how I could achieve this result. So far I have attempted to use many methods, including string.copy() to copy parts of the string to a character array:

1
2
length = line.copy(c,12,4);
c[length] = '\0';


But this approach isn't anywhere close to correct. It stores the values as:

1
2
3
4
5
6
7
c[0] = '0';
c[1] = '1';
c[2] = '2';
c[3] = '3';
c[4] = '4';
c[5] = '5';
// etc. 


It may be that the best method is to stream the hex values directly into the characters, but I am also unsure how I would do that. Any help is appreciated.
Last edited on
Well, you need to convert each pair of chars in the string into a single byte.

Each char corresponds to a nybble (or nibble) which has a value 0-F. So you need to convert the char to the corresponding value, hex-wise: 0->0, 1->1, ... E->14, F->15

Then a byte value = high_nybble * 16 + low_nybble (or you can use bit shifting)

Andy
Last edited on
I've implemented it as a function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
char Convert (string hexNumber)
{
  char aChar;
  char highOrderDig = hexNumber[0];
  char lowOrderDig  = hexNumber[1];
  int lowOrderValue = 0;
  int highOrderValue = 0;
  if (isdigit(highOrderDig))
    highOrderValue = atoi(&highOrderDig);
  else
    {
      switch (highOrderDig) {
      case 'a':
        highOrderValue = 10;
        break;
      case 'b':
        highOrderValue = 11;
        break;
      case 'c':
        highOrderValue = 12;
        break;
      case 'd':
        highOrderValue = 13;
        break;
      case 'e':
        highOrderValue = 14;
        break;
      case 'f':
        highOrderValue = 15;
        break;
      default:
        highOrderValue = 0;
      }
    }
  if (isdigit(lowOrderDig))
    lowOrderValue = atoi(&lowOrderDig);
  else
    {
      switch (lowOrderDig) {
      case 'a':
        lowOrderValue = 10;
        break;
      case 'b':
        lowOrderValue = 11;
        break;
      case 'c':
        lowOrderValue = 12;
        break;
      case 'd':
        lowOrderValue = 13;
        break;
      case 'e':
        lowOrderValue = 14;
        break;
      case 'f':
        lowOrderValue = 15;
        break;
      default:
        lowOrderValue = 0;
      }
    }
  aChar = lowOrderValue + 16 * highOrderValue;
  return aChar;
}



Which I then call in main() using

1
2
string aStr (line,0,2);
a = Convert(aStr);


Is there a better way to approach it than that switch statement?
Well, I would implement it using if()s...

You don't really need atoi when you are converting a single char. And you can exploit the fact the ranges '0', '1', '2', ... and 'a' ... 'f' are contiguous.

Also, the code for the low and high order nybbles is identical, so could be factored out into a helper function.
Sure, there will always be ways to do things differently. Below is how I would do it:

1
2
3
4
5
6
7
8
9
char hexchar; // assume this is one of the chars (ABCDEFabcdef)
int hexvalue;

if (hexchar >= 'A' && hexchar <= 'F') {
    hexvalue = hexchar - 55;
}
else if (hexchar >= 'a' && hexchar <= 'f') {
    hexvalue = hexchar - 87;
}


Now, before you use that, make sure you understand what it does. Make sure to try to understand it yourself (try not to ask anyone). It is pretty straight forward anyways.
Thank you very much. That answers my question.
Topic archived. No new replies allowed.