Since C ++ 11 and C99 are there, you can now parse the GUID string directly in the GUID structure using argument size specifiers like e. d. hh , which denotes single-byte data. However, the correct and portable way, which does not depend on the platform sizes long , int and short , is to use macros provided in <inttypes.h> (or <cinttypes> for C ++ 11):
#include <inttypes.h> #define G32 "%8" SCNx32 #define G16 "%4" SCNx16 #define G8 "%2" SCNx8 bool to_guid(const char* str, GUID* guid) { int nchars = -1; int nfields = sscanf(str, "{" G32 "-" G16 "-" G16 "-" G8 G8 "-" G8 G8 G8 G8 G8 G8 "}%n", &guid->Data1, &guid->Data2, &guid->Data3, &guid->Data4[0], &guid->Data4[1], &guid->Data4[2], &guid->Data4[3], &guid->Data4[4], &guid->Data4[5], &guid->Data4[6], &guid->Data4[7], &nchars); return nfields == 11 && nchars == 38; } #undef G8 #undef G16 #undef G32
Macros in <inttypes.h> can be defined differently by different compilers and bit systems; just for example, on my system they
#define SCNx8 "hhx" #define SCNx16 "hx" #define SCNx32 "x" #define SCNx64 "llx"
The %n at the end returns the length of the string processed so far, so if there is no line ending } , %n will not be reached, and nchars will have an initial value of -1, otherwise it will return the length of the GUID string, which must be 38 (otherwise, for example, the last byte can be parsed, even if it is one hexadecimal character that would not be valid for the GUID). %n itself is not considered a "field" for the sscanf return value.
This is still not fantastically correct, since the parser accepts spaces instead of leading zeros for each component, so there is a line with strategically placed spaces
{ FACFFB- C-4DF3-A06C-D4 1 A 2 B 3}
will still be sorted out as if he were
{00FACFFB-000C-4DF3-A06C-D4010A020B03}
but this is probably only possible with one sscanf .