I’m using this code to convert a hex string with fixed size 32 to a 16 byte uint8 array.
const uint8_t* c = "0123456789abcdef0123456789abcdef";
uint8_t Bytes[16];
for (int i = 0; i < 16; i++) {
sscanf (&c[2*i], "%2hhx", &(Bytes[i]));
}
Despite the hh specifying a target width of 1 byte, 4 bytes get written per step. Thus, the code writes 3 bytes past the end of the buffer. Why is that?
(For now, I fixed it using a temporary int that gets copied to the array on each step.)
To reproduce:
#include <stdint.h>
#include <string>
void main (int argc, char* argv[])
{
const char* c = "0123456789abcdef0123456789abcdef";
uint8_t b[20];
for (int i = 0; i < 20; i++) {
b[i] = i;
}
for (int i = 0; i < 16; i++) {
sscanf (&c[2*i], "%2hhx", &(b[i]));
}
for (int i = 0; i < 20; i++) {
fprintf(stdout, "%02x\n", (int)(b[i]));
}
}
The expected output is
01
23
45
67
89
ab
cd
ef
01
23
45
67
89
ab
cd
ef
10
11
12
13
However, the actual output using Visual Studio 2010 is:
01
23
…
cd
ef
00
00
00
13
There is a small problem with your code right in the beginning.
In C++, it is not specified whether a
charissignedorunsigned. More precisely, the typeschar,signed char,unsigned charare distinct, and in fact you have to take this into accountwhen overloading functions and specializing templates.
The code now is:
Let us analyse your format string:
With this info, it looks correct so far.
From what I can tell, there is no problem in a C99 conforming library *.
*: In this regard, the MSVC library does not support the
hhspecifier.