wie Hex-String in unsigned 64-Bit (uint64_t) integer in eine schnelle und sichere Art und Weise zu konvertieren?
-
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 ~
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".