Modifica: In c++17 o versioni successive from_chars
è preferito. Per ulteriori informazioni, vedere qui:https://topanswers.xyz/cplusplus?q=724#a839
Per un dato string str
ci sono diversi modi per farlo, ciascuno con vantaggi e svantaggi. Ho scritto un esempio dal vivo qui:https://ideone.com/LO2Qnq e ne discuto di seguito:
strtol
Come suggerito qui strtol
Il parametro out di ' può essere utilizzato per ottenere il numero di caratteri letti. strtol
restituisce effettivamente un long
non un int
quindi al ritorno sta succedendo un cast.
char* size;
const int num = strtol(str.c_str(), &size, 10);
if(distance(str.c_str(), const_cast<const char*>(size)) == str.size()) {
cout << "strtol: " << num << endl;
} else {
cout << "strtol: error\n";
}
Nota che questo utilizza str.c_str()
per fare riferimento alla stessa stringa. c_str
Restituisce il puntatore all'array sottostante che funge da memoria di caratteri non temporanea se si dispone di C++11:
Nota anche che il puntatore restituito da c_str
sarà valido tra il strtol
e distance
chiamate a meno che:
Se violi uno di questi casi, dovrai fare una copia temporanea di i
's sottostante const char*
ed eseguire il test su quello.
sscanf
sscanf
può usare %zn
per restituire il numero di caratteri letti che potrebbe essere più intuitivo rispetto a un confronto del puntatore. Se la base è importante, sscanf
potrebbe non essere una buona scelta. A differenza di strtol
e stoi
che supportano le basi 2 - 36, sscanf
fornisce specificatori solo per ottale (%o
), decimale (%d
) ed esadecimale (%x
).
size_t size;
int num;
if(sscanf(str.c_str(), "%d%zn", &num, &size) == 1 && size == str.size()) {
cout << "sscanf: " << num << endl;
} else {
cout << "sscanf: error\n";
}
stoi
Come suggerito qui stoi
il parametro di output funziona come sscanf
è %n
restituendo il numero di caratteri letti. In armonia con C++ questo richiede un string
ea differenza delle implementazioni C sopra stoi
lancia un invalid_argument
se il primo carattere non di spazi bianchi non è considerato una cifra per la base corrente, e questo purtroppo significa che a differenza delle implementazioni C questo deve verificare la presenza di un errore sia nel try
e catch
blocchi.
try {
size_t size;
const auto num = stoi(str, &size);
if(size == str.size()) {
cout << "stoi: " << num << endl;
} else {
throw invalid_argument("invalid stoi argument");
}
} catch(const invalid_argument& /*e*/) {
cout << "stoi: error\n";
}