sscanf(str, "%016llX", &int64);
ma non sembra al sicuro. C'è un modo veloce e sicuro per eseguire il casting di tipo?
Grazie ~
sscanf(str, "%016llX", &int64);
ma non sembra al sicuro. C'è un modo veloce e sicuro per eseguire il casting di tipo?
Grazie ~
Non preoccupatevi delle funzioni della famiglia scanf
. Sono quasi impossibili da usare in modo robusto. Ecco un uso sicuro generale 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 */
}
noti che strtoull
accetta un 0x
prefisso opzionale sulla corda, così come opzionale spazio bianco iniziale e un carattere di segno (+
o -
). Se si desidera rifiutare questi, è necessario eseguire un test prima di chiamare strtoull
, per esempio:
if (!isxdigit(str[0]) || (str[1] && !isxdigit(str[1])))
Se anche voi volete disabilitare eccessivamente lunghe rappresentazioni di numeri (zeri), si potrebbe verificare la seguente condizione prima di chiamare strtoull
:
if (str[0]=='0' && str[1])
una cosa da tenere a mente è che "i numeri negativi" non sono considerati al di fuori della gamma di conversione; invece, un prefisso di -
viene trattato come l'operatore di negazione unario in C applicato a un valore senza segno, quindi ad esempio strtoull("-2", 0, 16)
restituirà ULLONG_MAX-1
(senza impostare errno
).
In generale sono d'accordo con i tuoi sentimenti riguardo alla famiglia 'scanf()'. Essi * hanno senso in ambienti controllati, ad es. leggendo nei file che la tua applicazione ha scritto da sola – DevSolar
@DevSolar: In effetti, il mio commento era inteso come una risposta alla domanda dell'OP sull'uso sicuro, non su un consiglio generale. La famiglia 'scanf' funziona bene per la lettura dei file di Linux'/proc', per esempio. –
Non '' strtoull() 'restituisce un tipo 'unsigned long long', che non è necessariamente un tipo 'uint64_t'? – GreySage
Il titolo (attualmente) contraddice il codice che hai fornito. Se vuoi fare quello che era originariamente il tuo titolo (converti una stringa in un intero), allora puoi usare questa risposta.
È possibile utilizzare la funzione di strtoull
, che a differenza sscanf
è una funzione specificamente orientata verso la lettura di rappresentazioni testuali di numeri.
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
}
A mio parere, vuole convertire da intero a stringa, non viceversa. ;) – Flinsch
@Flinsch, il titolo è cambiato, ma il suo codice originale suggerisce di voler convertire da stringa a intero. Non sono sicuro che tu possa vedere la cronologia delle modifiche della domanda, ma in origine il titolo indicava che voleva convertire una stringa in un numero intero. – dreamlax
In realtà, 'scanf()' et al. sono * definiti * in termini di 'strtol()'. Per l'input decente a metà, sono funzionalmente identici per quanto riguarda i numeri di analisi. Ammetto che 'strtol()' gestisce il fallimento in modo più garbato. – DevSolar
Al momento ho scritto questa risposta, il titolo ha suggerito che ci si vuole scrivere un int64_t in una stringa, mentre il codice ha fatto il contrario (la lettura di una stringa esadecimale in un int64_t). Ho risposto "entrambi i modi":
L'intestazione <inttypes.h>
ha macro di conversione per gestire le ..._t
tipi in modo sicuro:
#include <stdio.h>
#include <inttypes.h>
sprintf(str, "%016" PRIX64, int64);
Oppure (se questo è davvero quello che stai cercando di fare), il contrario :
#include <stdio.h>
#include <inttypes.h>
sscanf(str, "%" SCNx64, &int64);
Notare che non è possibile applicare le larghezze, ecc con la famiglia scanf()
funzioni. Analizza ciò che ottiene, il che può produrre risultati indesiderati quando l'input non aderisce alla formattazione prevista. Oh, e la famiglia di funzioni scanf()
conosce solo (in minuscolo) "x", non (maiuscolo) "X".
Cosa intendi con "non sicuro"? –
Non lo so. Ho provato ad usarlo per eseguire il cast tra un gran numero di stringhe esadecimali e a volte segnalerei un errore di segmento –
Potresti mostrare la dichiarazione e l'inizializzazione di 'str'? – Flinsch