Print a GUID variable

Print a GUID variable



I have a GUID variable and I want to write inside a text file its value.
GUID definition is:


typedef struct _GUID // size is 16
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
GUID;



But I want to write its value like:


CA04046D-0000-0000-0000-504944564944



I observed that:


Data1


Data2


Data3



But what about the others?



I have to interpret myself this values in order to get that output or is there a more direct method to print such a variable?






Variables hold values, and values do not have a base. It may be displayed as decimal, hexidecimal, binary, or any other base as part of the "printing" function, but the value itself has no base and so is not "decimal".

– Mooing Duck
Aug 7 '13 at 22:08





11 Answers
11



Use the StringFromCLSID function to convert it to a string



e.g.:


GUID guid;
CoCreateGuid(&guid);

OLECHAR* guidString;
StringFromCLSID(guid, &guidString);

// use guidString...

// ensure memory is freed
::CoTaskMemFree(guidString);



Also see the MSDN definition of a GUID for a description of data4, which is an array containing the last 8 bytes of the GUID






using bstr as the prefix here is misleading as BSTR is a type and it is freed with SysFreeString(), not CoTaskMemFree(). I'd rename this to guidString, or guidStringCoTaskMemAlloc to be really explicit. OLECHAR is a vestige from 16 bit days, use wchar_t or WCHAR instead, better yet PWSTR as that includes the SAL annotation for "null terminated"

– Chris Guzak
May 15 '15 at 23:12







StringFromGUID2() can be used to avoid the allocation, it puts its result in a caller specified buffer. this avoids the possibility of failure and the need to free the result.

– Chris Guzak
May 15 '15 at 23:18






The link you gave says that Data4 contains values, not a pointer to an array as you say in the comment.

– Serge Rogatch
Jun 18 '15 at 15:37






@SergeRogatch I think I wrote that because C++ treats array types similar to a pointer to a single element... I'll change the wording to make it less confusing

– John Sibly
Jun 19 '15 at 9:36



Sometimes its useful to roll your own. I liked fdioff's answer but its not quite right. There are 11 elements of different sizes.


printf("Guid = %08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
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]);

Output: "Guid = 44332211-1234-ABCD-EFEF-001122334455"



Refer to Guiddef.h for the GUID layout.



Same, as a method:


void printf_guid(GUID guid)
printf("Guid = %08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
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]);



you can also pass a CLSID to this method.






worked like a champ! I'm messing with some BLE structures that have UUID aka GUID. I set: GUID *guid = &pCharBuffer->CharacteristicUuid.Value.LongUuid; and used the printf above. thanks for sharing!

– Gilson
Aug 27 '14 at 19:37







I had to change each %02hhX into %02hX for it to work.

– Brian THOMAS
Feb 24 '17 at 16:06



In case when your code uses ATL/MFC you also could use CComBSTR::CComBSTR(REFGUID guid) from atlbase.h:


CComBSTR::CComBSTR(REFGUID guid)


atlbase.h


GUID guid = ...;
const CComBSTR guidBstr(guid); // Converts from binary GUID to BSTR
const CString guidStr(guidBstr); // Converts from BSTR to appropriate string, ANSI or Wide



It will make conversion & memory cleanup automatically.



In case you prefer C++ way


std::ostream& operator<<(std::ostream& os, REFGUID guid)

os << std::uppercase;
os.width(8);
os << std::hex << guid.Data1 << '-';

os.width(4);
os << std::hex << guid.Data2 << '-';

os.width(4);
os << std::hex << guid.Data3 << '-';

os.width(2);
os << std::hex
<< static_cast<short>(guid.Data4[0])
<< static_cast<short>(guid.Data4[1])
<< '-'
<< static_cast<short>(guid.Data4[2])
<< static_cast<short>(guid.Data4[3])
<< static_cast<short>(guid.Data4[4])
<< static_cast<short>(guid.Data4[5])
<< static_cast<short>(guid.Data4[6])
<< static_cast<short>(guid.Data4[7]);
os << std::nouppercase;
return os;



Usage:


static const GUID guid =
0xf54f83c5, 0x9724, 0x41ba, 0xbb, 0xdb, 0x69, 0x26, 0xf7, 0xbd, 0x68, 0x13 ;

std::cout << guid << std::endl;



Output:



F54F83C5-9724-41BA-BBDB-6926F7BD6813






I'm assuming those std::cout.width()'s should be os.width() ?

– Soylent Graham
Sep 30 '15 at 13:42






Exactly, thank you for noticing

– Yuri S. Cherkasov
Oct 9 '15 at 8:23






You need os.fill('0') at the start, and the width needs to be repeated for every byte of Data4.

– Willem Hengeveld
Mar 9 '16 at 18:07



Inspired by JustinB's answer


#define GUID_FORMAT "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX"
#define GUID_ARG(guid) 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]



and then


printf("Int = %d, string = %s, GUID = " GUID_FORMAT "n", myInt, myString, GUID_ARG(myGuid));



You can eliminate the need for special string allocations/deallocations by using StringFromGUID2()


GUID guid = <some-guid>;
// note that OLECHAR is a typedef'd wchar_t
wchar_t szGUID[64] = 0;
StringFromGUID2(&guid, szGUID, 64);






these are not BSTRs, those are freed with SysFreeString(), StringFromCLSID result is freed with CoTaskMemAlloc

– Chris Guzak
Jul 13 '17 at 18:57






Well, the advantage of using StringFromGUID2() is that you don't have to do any COM or BSTR string deallocations. You pass it plain ol' memory, and it writes characters there. An OLECHAR is just a typedef'd wchar_t.

– Tim Dowty
Oct 12 '17 at 17:40




Courtesy of google's breakpad project:


std::string ToString(GUID *guid)
char guid_string[37]; // 32 hex chars + 4 hyphens + null terminator
snprintf(
guid_string, sizeof(guid_string) / sizeof(guid_string[0]),
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
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]);
return guid_string;


UUID guid = 0;
UuidCreate(&guid);
std::cout << GUIDToString(&guid);






Thanks! The sample doesn't compile unless I replace sprintf with snprintf...

– AntonK
Jul 25 '17 at 14:35






Someone suggested that the correct answer should use snprint(). It seems correct, as sprintf() doesn't take a size_t as second argument. However your link actually uses swprintf(). @Marco, could you please confirm what was your intention with this answer, perhaps by fixing it to use sprintf or accepting snprintf or something else?

– giusti
Sep 13 '18 at 3:41



snprint()


sprintf()


size_t


swprintf()


sprintf


snprintf






I've fixed it. Thanks for the feedback.

– Marco M.
Sep 13 '18 at 18:34



I know the question is quite old, but would this work maybe?


inline std::ostream& operator <<(std::ostream& ss,GUID const& item)
OLECHAR* bstrGuid;
::StringFromCLSID(item, &bstrGuid);
ss << bstrGuid;
::CoTaskMemFree(bstrGuid);
return ss;






Well...if you've tried it, and it works, then yes

– b1nary.atr0phy
May 20 '12 at 2:28



Use UuidToString function to convert GUID to string. The function accepts UUID type which is typedef of GUID.


std::string
GuidToString(const GUID& guid, bool lower = false)

const char* hexChars = lower ? "0123456789abcdef" : "0123456789ABCDEF";

auto f = [hexChars](char* p, unsigned char v)

p[0] = hexChars[v >> 4];
p[1] = hexChars[v & 0xf];
;

char s[36];
f(s, static_cast<unsigned char>(guid.Data1 >> 24));
f(s + 2, static_cast<unsigned char>(guid.Data1 >> 16));
f(s + 4, static_cast<unsigned char>(guid.Data1 >> 8));
f(s + 6, static_cast<unsigned char>(guid.Data1));
s[8] = '-';
f(s + 9, static_cast<unsigned char>(guid.Data2 >> 8));
f(s + 11, static_cast<unsigned char>(guid.Data2));
s[13] = '-';
f(s + 14, static_cast<unsigned char>(guid.Data3 >> 8));
f(s + 16, static_cast<unsigned char>(guid.Data3));
s[18] = '-';
f(s + 19, guid.Data4[0]);
f(s + 21, guid.Data4[1]);
s[23] = '-';
f(s + 24, guid.Data4[2]);
f(s + 26, guid.Data4[3]);
f(s + 28, guid.Data4[4]);
f(s + 30, guid.Data4[5]);
f(s + 32, guid.Data4[6]);
f(s + 34, guid.Data4[7]);

return std::string(s, 36);


printf(%X-%X-%X-%X-%X", guid.Data1, guid.Data2, guid.Data3, &guid.Data4);



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)