2009-11-04 6 views
27

Tôi có biến GUID và tôi muốn ghi bên trong tệp văn bản giá trị của nó. GUID định nghĩa là:In biến GUID

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

Nhưng tôi muốn viết giá trị của nó như:

CA04046D-0000-0000-0000-504944564944 

tôi quan sát thấy rằng:

  • Data1 giữ giá trị thập phân cho CA04046D
  • Data2 giữ giá trị thập phân cho 0
  • Data3 giữ giá trị thập phân cho tiếp theo 0

Nhưng còn những điểm khác thì sao?

Tôi phải tự giải thích các giá trị này để có được kết quả đó hoặc có phương pháp trực tiếp hơn để in biến đó không?

+0

Biến giữ giá trị và giá trị không có cơ sở. Nó có thể được hiển thị dưới dạng thập phân, thập lục phân, nhị phân hoặc bất kỳ cơ sở nào khác như là một phần của chức năng "in", nhưng bản thân giá trị không có base và do đó là _not_ "decimal". –

Trả lời

41

Sử dụng StringFromCLSID chức năng để chuyển đổi nó thành một chuỗi

ví dụ:

GUID guid; 
CoCreateGuid(&guid); 

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

// use guidString... 

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

Cũng thấy MSDN definition of a GUID cho một mô tả về data4, mà là một mảng chứa 8 byte cuối cùng của GUID

+1

sử dụng bstr làm tiền tố ở đây là gây hiểu nhầm vì BSTR là một kiểu và nó được giải phóng với SysFreeString(), không phải là CoTaskMemFree(). Tôi muốn đổi tên này thành guidString hoặc guidStringCoTaskMemAlloc thực sự rõ ràng. OLECHAR là một di tích từ 16 bit ngày, sử dụng wchar_t hoặc WCHAR thay vào đó, tốt hơn PWSTR vì bao gồm chú thích SAL cho "null terminated" –

+3

StringFromGUID2() có thể được sử dụng để tránh phân bổ, nó đặt kết quả của nó trong bộ đệm được chỉ định của người gọi . điều này tránh được khả năng thất bại và cần phải giải phóng kết quả. –

+0

Liên kết bạn đã cho biết rằng Data4 chứa các giá trị, không phải là một con trỏ tới một mảng như bạn nói trong nhận xét. –

2

Tôi biết câu hỏi là khá cũ, nhưng điều này có thể làm việc?

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

Vâng ... nếu bạn đã thử nó, và nó hoạt động , sau đó có –

10

Trong trường hợp khi mã của bạn sử dụng ATL/MFC bạn cũng có thể sử dụng CComBSTR::CComBSTR(REFGUID guid) từ 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 

Nó sẽ làm cho chuyển đổi & bộ nhớ dọn dẹp tự động.

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

Đôi khi hữu ích khi cuộn của riêng bạn. Tôi thích câu trả lời của fdioff nhưng nó không hoàn toàn đúng. Có 11 thành phần có kích thước khác nhau.

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

Tham khảo Guiddef.h để bố cục GUID.

Same, như một phương pháp:

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

bạn cũng có thể vượt qua một CLSID đến phương pháp này.

+0

làm việc như một nhà vô địch! Tôi đang rối tung với một số cấu trúc BLE có UUID aka GUID. Tôi đặt: GUID * guid = & pCharBuffer-> CharacteristicUuid.Value.LongUuid; và sử dụng printf ở trên. cám ơn vì đã chia sẻ! – Gilson

+0

Tôi phải thay đổi mỗi% 02hhX thành% 02hX để nó hoạt động. –

2

Bạn có thể loại bỏ sự cần thiết của việc phân bổ chuỗi đặc biệt/deallocations bằng cách sử dụng StringFromGUID2()

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

đây không phải là BSTR, những người được giải phóng với SysFreeString(), StringFromCLSID kết quả được giải phóng với CoTaskMemAlloc –

+1

Vâng, lợi thế của việc sử dụng StringFromGUID2() là bạn không phải thực hiện bất kỳ thỏa thuận chuỗi COM hoặc BSTR nào. Bạn vượt qua nó bộ nhớ ol 'đồng bằng, và nó viết nhân vật ở đó. Một OLECHAR chỉ là một typedef'd wchar_t. –

2

Courtesy of google's breakpad dự án:

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

Cảm ơn! Các mẫu không biên dịch trừ khi tôi thay thế sprintf với snprintf ... – AntonK

6

Lấy cảm hứng từ JustinB 's câu trả lời

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

và sau đó

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

Trong trường hợp bạn thích C++ cách

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

Cách sử dụng:

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

+0

Tôi giả sử những std :: cout.width() 's nên được os.width()? –

+0

Chính xác, cảm ơn bạn đã thông báo –

+2

Bạn cần có os.fill ('0') lúc bắt đầu và chiều rộng cần được lặp lại cho mỗi byte của Data4. –

1

Sử dụng chức năng UuidToString để chuyển đổi GUID thành chuỗi. Hàm này chấp nhận kiểu UUID là typedef của GUID.