2009-11-04 262 views
27

我有一个GUID变量,我想在文本文件中写入它的值。 GUID的定义是:打印一个GUID变量

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

但我想写它的价值,如:

CA04046D-0000-0000-0000-504944564944 

我观察到:

  • Data1适用于CA04046D
  • Data2拥有十进制值0的十进制值
  • Data3保留下一个0的十进制值

但是其他的呢?

为了得到那个输出或者是否有更直接的方法来打印这样的变量,我必须解释我自己这个值?

+0

变量保存值,并且值没有基数。它可以作为“打印”功能的一部分显示为十进制,十六进制,二进制或任何其他基础,但该值本身没有基数,因此是_not_“decimal”。 – 2013-08-07 22:08:49

回答

41

使用StringFromCLSID函数将其转换为一个字符串

例如:

GUID guid; 
CoCreateGuid(&guid); 

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

// use guidString... 

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

还请参阅MSDN definition of a GUID为DATA4的描述,其是包含的最后8个字节GUID

的阵列
+1

使用bstr作为前缀在这里是误导,因为BSTR是一种类型,它是用SysFreeString()而不是CoTaskMemFree()释放的。我会将其重命名为guidString,或者guidStringCoTaskMemAlloc以确实显式。 OLECHAR是一个来自16位天的痕迹,使用wchar_t或WCHAR来代替,更好的还是PWSTR,因为它包含用于“空终止”的SAL注释 – 2015-05-15 23:12:28

+3

StringFromGUID2()可用于避免分配,它将其结果放入调用程序指定的缓冲区。这避免了失败的可能性和需要释放结果。 – 2015-05-15 23:18:37

+0

您给出的链接表示Data4包含值,而不是像在注释中所说的那样指向数组的指针。 – 2015-06-18 15:37:58

2

我知道这个问题是相当古老的,但这项工作可能吗?

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

呃...如果您已经尝试过它, ,然后是 – 2012-05-20 02:28:31

10

在当你的代码使用ATL情况/ MFC你也可以使用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 

它会自动进行转换&内存清理。

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

有时它有用于推出自己的。我喜欢fdioff的回答,但它不太正确。有11个不同大小的元素。

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}" 

有关GUID布局,请参阅Guiddef.h。

同样,作为一种方法:

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]); 
} 

,你也可以通过一个CLSID这种方法。

+0

像冠军一样工作!我搞砸了一些具有UUID又称为GUID的BLE结构。我设置了:GUID * guid =&pCharBuffer-> CharacteristicsUuid.Value.LongUuid;并使用了上面的printf。感谢分享! – Gilson 2014-08-27 19:37:35

+0

我必须将每个%02hhX更改为%02hX才能正常工作。 – 2017-02-24 16:06:00

2

您可以通过使用StringFromGUID2()消除对特殊字符串分配/释放操作需要

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

这些不是BSTRs,那些被释放的SysFreeString(),StringFromCLSID结果被释放与CoTaskMemAlloc – 2017-07-13 18:57:59

+1

那么,使用StringFromGUID2()的优点是,你不必做任何COM或BSTR字符串释放。你把它传递给普通的记忆,它在那里写字。 OLECHAR只是一个typedef'd wchar_t。 – 2017-10-12 17:40:11

2

google's breakpad项目的礼貌:

std::string ToString(GUID *guid) { 
    char guid_string[37]; // 32 hex chars + 4 hyphens + null terminator 
    sprintf(
      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); 
+0

谢谢!该示例不会编译,除非我用snprintf替换sprintf ... – AntonK 2017-07-25 14:35:39

6

通过JustinB的回答启发

#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] 

然后

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

如果你喜欢C++方式

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; 
} 

用法:

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

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

输出:

F54F83C5-9724-41BA-BBDB-6926F7BD6813

+0

我假设那些std :: cout.width()的应该是os.width()? – 2015-09-30 13:42:40

+0

正好,感谢您注意 – 2015-10-09 08:23:56

+2

您需要在开始时使用os.fill('0'),并且需要为Data4的每个字节重复宽度。 – 2016-03-09 18:07:49

1

使用UuidToString函数将GUID转换为字符串。该函数接受UID类型,它是GUID的typedef。