2009-11-04 359 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。