wie Hex-String in unsigned 64-Bit (uint64_t) integer in eine schnelle und sichere Art und Weise zu konvertieren?

StackOverflow https://stackoverflow.com/questions/4132318

  •  29-09-2019
  •  | 
  •  

Frage

Ich habe versucht,

sscanf(str, "%016llX", &int64 );

scheint aber nicht sicher. Gibt es eine schnelle und sichere Art und Weise die Art Casting zu tun?

Dank ~

War es hilfreich?

Lösung

Sie nicht mit Funktionen in der scanf Familie kümmern. Sie sind fast unmöglich, robust zu verwenden. Hier ist eine allgemeine sichere Verwendung von strtoull:

char *str, *end;
unsigned long long result;
errno = 0;
result = strtoull(str, &end, 16);
if (result == 0 && end == str) {
    /* str was not a number */
} else if (result == ULLONG_MAX && errno) {
    /* the value of str does not fit in unsigned long long */
} else if (*end) {
    /* str began with a number but has junk left over at the end */
}

Beachten Sie, dass strtoull akzeptiert einen optionalen 0x Präfix auf der Saite, sowie optional Anfänge Leerzeichen und Zeichen-Zeichen (+ oder -). Wenn Sie diese ablehnen mögen, sollten Sie einen Test durchführen, bevor strtoull Aufruf, zum Beispiel:

if (!isxdigit(str[0]) || (str[1] && !isxdigit(str[1])))

Wenn Sie auch zu lange Darstellungen von Zahlen nicht zulassen wollen (führende Nullen), könnten Sie die folgende Bedingung überprüfen, bevor strtoull Aufruf:

if (str[0]=='0' && str[1])

Eine weitere Sache im Auge zu behalten ist, dass „negativen Zahlen“ nicht außerhalb des Bereichs der Umwandlung in Betracht gezogen; Stattdessen wird ein Präfix von - behandelt die gleiche wie die unären Negationsoperator in C auf einen Wert ohne Vorzeichen angelegt wird, so wird beispielsweise strtoull("-2", 0, 16) ULLONG_MAX-1 zurück (ohne errno Einstellung).

Andere Tipps

Ihr Titel (derzeit) widerspricht der Code, den Sie zur Verfügung gestellt. Wenn Sie wollen, zu tun, was Ihr Titel war ursprünglich (eine Zeichenfolge in eine ganze Zahl konvertieren), dann können Sie diese Antwort verwenden.


könnten Sie verwenden die strtoull -Funktion, die im Gegensatz zu sscanf a Funktion speziell ausgerichtet auf Textdarstellungen von Zahlen zu lesen.

const char *test = "123456789abcdef0";

errno = 0;
unsigned long long result = strtoull(test, NULL, 16);

if (errno == EINVAL)
{
    // not a valid number
}
else if (errno == ERANGE)
{
    // does not fit in an unsigned long long
}

Zu der Zeit ich diese Antwort schrieb, Ihr Titel vorgeschlagen, dass Sie eine uint64_t in einen String schreiben wollen würden, während Ihr Code das Gegenteil tat (einen Hex-String in eine uint64_t lesen). Ich antwortete: "in beiden Richtungen":

Der <inttypes.h> Header hat Konvertierungsmakros die ..._t Typen sicher gehandhabt werden:

#include <stdio.h>
#include <inttypes.h>

sprintf( str, "%016" PRIx64, uint64 );

oder (wenn das in der Tat, was Sie versuchen zu tun), andersrum:

#include <stdio.h>
#include <inttypes.h>

sscanf( str, "%" SCNx64, &uint64 );

Beachten Sie, dass Sie nicht Breiten usw. mit der scanf() Funktion Familie erzwingen kann. Es analysiert, was es wird, was unerwünschte Ergebnisse liefern kann, wenn der Eingang nicht einhält erwartete Formatierung. Oh, und die scanf() Funktion Familie nur weiß (klein geschrieben) "x", nicht (in Großbuchstaben) "X".

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top