2009-11-04 11 views
27

J'ai une variable GUID et je veux écrire sa valeur dans un fichier texte. définition GUID est:Imprimer une variable GUID

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

Mais je veux écrire sa valeur comme:

CA04046D-0000-0000-0000-504944564944 

Je remarquai que:

  • Data1 contient la valeur décimale pour CA04046D
  • Data2 détient la valeur décimale pour 0
  • Data3 contient la valeur décimale pour la prochaine 0

Mais qu'en est-il des autres?

Je dois interpréter moi-même ces valeurs pour obtenir cette sortie ou existe-t-il une méthode plus directe pour imprimer une telle variable?

+0

Les variables contiennent des valeurs et les valeurs n'ont pas de base. Il peut être affiché comme décimal, hexadécimal, binaire, ou toute autre base dans le cadre de la fonction "impression", mais la valeur elle-même n'a pas de base et est donc _not_ "décimal". –

Répondre

41

utiliser la fonction StringFromCLSID pour le convertir en une chaîne

par exemple:

GUID guid; 
CoCreateGuid(&guid); 

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

// use guidString... 

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

Voir aussi la MSDN definition of a GUID pour une description de données4, qui est un tableau contenant les 8 derniers octets du GUID

+1

en utilisant bstr comme préfixe ici est trompeur car BSTR est un type et il est libéré avec SysFreeString(), pas CoTaskMemFree(). Je renommerais ceci à guidString, ou guidStringCoTaskMemAlloc pour être vraiment explicite. OLECHAR est un vestige de 16 bits, utilisez wchar_t ou WCHAR à la place, mieux encore PWSTR car cela inclut l'annotation SAL pour "null terminé" –

+3

StringFromGUID2() peut être utilisé pour éviter l'allocation, il met son résultat dans un tampon spécifié par l'appelant . cela évite la possibilité d'échec et la nécessité de libérer le résultat. –

+0

Le lien que vous avez indiqué indique que Data4 contient des valeurs et non un pointeur sur un tableau, comme vous le dites dans le commentaire. –

2

Je sais que la question est assez ancienne, mais cela fonctionnerait-il peut-être?

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

Eh bien ... si vous l'avez essayé, et ça marche , alors oui –

10

Dans le cas où votre code utilise ATL/MFC vous avez également pu utiliser CComBSTR::CComBSTR(REFGUID guid) de 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 

Il fera le nettoyage de la mémoire de conversion & automatiquement.

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

Il est parfois utile de rouler la vôtre. J'ai aimé la réponse de fdioff mais ce n'est pas tout à fait vrai. Il y a 11 éléments de différentes tailles.

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

Reportez-vous à Guiddef.h pour la mise en page GUID.

même, comme méthode:

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

vous pouvez également passer un CLSID à cette méthode.

+0

a travaillé comme un champion! Je suis en train de jouer avec certaines structures BLE qui ont UUID aka GUID. Je définis: GUID * guid = & pCharBuffer-> CharacteristicUuid.Value.LongUuid; et utilisé le printf ci-dessus. Merci d'avoir partagé! – Gilson

+0

Je devais changer chaque% 02hhX en% 02hX pour que cela fonctionne. –

2

Vous pouvez éliminer la nécessité d'une allocation de chaînes spéciales/désallocations en utilisant StringFromGUID2()

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

ce ne sont pas des BSTR, ceux-ci sont libérés avec SysFreeString(), le résultat StringFromCLSID est libéré avec CoTaskMemAlloc –

+1

Eh bien, l'avantage d'utiliser StringFromGUID2() est que vous n'avez pas besoin de faire de libérations de chaînes COM ou BSTR. Vous lui passez votre mémoire, et il y écrit des caractères. Un OLECHAR est juste un typedef'd wchar_t. –

2

Avec l'aimable autorisation de google's breakpad projet:

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

Merci! L'exemple ne compile pas sauf si je remplace sprintf par snprintf ... – AntonK

6

Inspiré par la réponse de 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] 

puis

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

Si vous préférez C++ façon

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

Utilisation:

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

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

Sortie:

F54F83C5-9724-41BA-BBDB-6926F7BD6813

+0

Je suppose que std :: cout.width() devrait être os.width()? –

+0

Exactement, merci de remarquer –

+2

Vous avez besoin d'os.fill ('0') au début, et la largeur doit être répétée pour chaque octet de Data4. –

1

Utilisez la fonction UuidToString pour convertir le GUID en chaîne. La fonction accepte le type UUID qui est typedef de GUID.