Convertir la cadena a GUID con sscanf

Estoy tratando de convertir una cadena a GUID con sscanf:

GUID guid;
sscanf( "11111111-2222-3333-4455-667788995511", "%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]);

Sin embargo, en tiempo de ejecución, se produce un error y se cierra con «Error: error de Comando». Por qué? Cómo solucionarlo?

No quiero compilar con /clr por lo que no puede utilizar System.

OriginalEl autor Andy Li | 2010-05-13

4 Kommentare

  1. 5

    Donde no «Error: error de Comando»? No es un mensaje de error estándar…

    Puede utilizar el UuidFromString función a hacerlo en C++ nativo.

    +1 — Mote que UuidFromString es sólo para Windows.
    Estoy de codificación en haXe la orientación de c++, así que tal vez el error es de la haXe programa de pruebas… Pero el código de la pregunta es en puro c++. Cuando yo uso UuidFromString("11111111-2222-3333-4455-667788995511",&guid); dice error C2664: 'UuidFromStringA' : cannot convert parameter 1 fr om 'const char *' to 'RPC_CSTR'
    Cierto, pero él dijo que no quería usar «/clr», que también es sólo para Windows, así que pensé que era una buena suposición de hacer.
    Yo creo que una simple pieza se trabajo: const char *str = "..."; UuidFromString((RPC_CSTR) str, &guid);
    Oh, tienes razón. Muchas gracias!

    OriginalEl autor Dean Harding

  2. 8

    Creo que están dañando la pila. X especificador de tipo requiere puntero a int, que es al menos de 4 bytes, por lo que a partir de &guid.De datos[4] parámetro que has jodido. Proporcionar suficiente espacio para sscanf y usted debería estar bien. Código Final se parece a esto:

        GUID guid;
    
        unsigned long p0;
        int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
    
        int err = sscanf_s(s.c_str(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
            &p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
    
        guid.Data1 = p0;
        guid.Data2 = p1;
        guid.Data3 = p2;
        guid.Data4[0] = p3;
        guid.Data4[1] = p4;
        guid.Data4[2] = p5;
        guid.Data4[3] = p6;
        guid.Data4[4] = p7;
        guid.Data4[5] = p8;
        guid.Data4[6] = p9;
        guid.Data4[7] = p10;

    OriginalEl autor Ivan G.

  3. 2

    Desde C++11 y C99 están ahí fuera, ahora es posible analizar un GUID de la cadena de la derecha en el GUID de la estructura, utilizando argumento de el tamaño de los especificadores de tales como el correo. g. hh que representa un solo byte de datos. Sin embargo, la correcta y portátil, de manera que no dependen de la plataforma tamaños de long, int y short es el uso de macros siempre en <inttypes.h> (o <cinttypes> para C++11):

    #include <inttypes.h>
    
    #define G32 "%8" SCNx32
    #define G16 "%4" SCNx16
    #define G8  "%2" SCNx8
    
    bool to_guid(const char* str, GUID* guid) {
      int nchars = -1;
      int nfields =
        sscanf(str, "{" G32 "-" G16 "-" G16 "-" G8 G8 "-" G8 G8 G8 G8 G8 G8 "}%n",
               &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],
               &nchars);
      return nfields == 11 && nchars == 38;
    }
    
    #undef G8
    #undef G16
    #undef G32

    Las macros en el <inttypes.h> puede ser definido de manera diferente por diferentes compiladores y sistema de bits; sólo por el bien de un ejemplo, en mi sistema se definen en <inttypes.h> como

    #define SCNx8        "hhx"
    #define SCNx16       "hx"
    #define SCNx32       "x"
    #define SCNx64       "llx"

    La %n especificador al final devuelve la longitud de la cadena analizada «hasta el momento», por lo que si la cadena es que falta el final }, %n no se alcanzaría, y nchars tendrá el valor inicial de -1, de lo contrario se devolverá a la longitud de la cadena GUID, que debe ser de 38 (de lo contrario, el correo. g. el último byte puede analizar incluso si se trata de un único hex personaje, que sería válido para un GUID). El %n no se cuentan como un «campo» para los fines de sscanf‘s valor de retorno.

    Todavía no es fantásticamente correcta, como el analizador acepta espacios en lugar de ceros a la izquierda de cada componente, de manera que la cuerda con estratégicamente espacios

    {  FACFFB-   C-4DF3-A06C-D4 1 A 2 B 3}

    todavía analizar como si fuera

    {00FACFFB-000C-4DF3-A06C-D4010A020B03}

    pero esto es probablemente lo mas lejos que se puede conseguir con una sola sscanf.

    OriginalEl autor kkm

  4. 0

    También puede utilizar CLSIDFromString si quieres evitar RPCRT4.DLL la dependencia CLSID es simplemente un GUID, por lo que el trabajo a pesar de los poco confuso nombre.

    ‘Lo creo que volverá buscando un ProgID cadena en el registro si el UUID no está en el formato correcto (IIDFromString() no será, sin embargo, pero requiere curlies). Además, sólo hay un widechar versión de la misma. A menos que se use COM, yo no iría con él (y que había una dependencia de OLE2.DLL en lugar de RPCRT4, que no es un intercambio justo). Raymond Chen tiene más: blogs.msdn.microsoft.com/oldnewthing/20151015-00/?p=91351

    OriginalEl autor EFraim

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea