http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
Rückgabewert
Bei Erfolg gibt die Funktion die konvertierte ganze Zahl als zurück int
Wert.
Wenn keine gültige Konvertierung durchgeführt werden konnte, wird ein Nullwert zurückgegeben.
Wenn der korrekte Wert außerhalb des Bereichs darstellbarer Werte liegt, wird INT_MAX oder INT_MIN zurückgegeben.
Also, wie ich zwischen unterscheide atoi("poop")
und atoi("0")
und atoi("0000000")
Ja ich kann Schleife und überprüfe auf alle Nullen, falls ich ein 0-Ergebnis erhalte, aber gibt es keinen besseren Weg?
Hinweis: Ich verwende ANSI C89
Das ist einer der Gründe atoi
wird manchmal als unsicher angesehen. Verwenden strtol
/ strtoul
stattdessen. Und wenn Sie es haben, verwenden Sie es strtonum
.
Die Funktion atoi
ist gefährlicher als man denkt. Das POSIX
Standard sagt:
Wenn der Wert nicht dargestellt werden kann, ist das Verhalten undefiniert.
Der C99-Standard sagt dies auch:
7.20.1
Die Funktionen atof, atoi, atol und atoll müssen den Wert des ganzzahligen Ausdrucks errno bei einem Fehler nicht beeinflussen. Wenn der Wert des Ergebnisses nicht dargestellt werden kann, ist das Verhalten undefiniert.
Wie von @cnicutar und @ouah beschrieben, atoi
kann eine gültige 0 nicht von einer ungültigen Zeichenfolge unterscheiden, die das macht strtol
Familie bessere Möglichkeiten.
Aber Wieso den? und Wie? Verstehen Sie zuerst, dass beides atoi
und strtol
Konvertieren Sie nur die anfängliche Menge von Zahlen in einer Zeichenfolge in numerische Werte. Alle nachgestellten nicht numerischen Zeichen werden einfach ignoriert. strtol
kann verwendet werden, um nach ungültigen Zeichenfolgen zu suchen, da es zusätzlich zu einem numerischen Wert auch einen Zeiger auf das Ende des numerischen Teils der Zeichenfolge zurückgibt. Also wenn das end
Zeiger immer noch auf den Anfang des ursprünglichen Strings verweist, können Sie erkennen, dass ein Fehler aufgetreten ist und keine Zeichen aus dem String konvertiert wurden.
Es gibt ein paar andere Feinheiten, wie im Codebeispiel zu sehen:
long lnum;
int num;
char *end;
errno = 0;
lnum = strtol(in_str, &end, 10); //10 specifies base-10
if (end == in_str) //if no characters were converted these pointers are equal
fprintf(stderr, "ERROR: can't convert string to number\n");
//If sizeof(int) == sizeof(long), we have to explicitly check for overflows
if ((lnum == LONG_MAX || lnum == LONG_MIN) && errno == ERANGE)
fprintf(stderr, "ERROR: number out of range for LONG\n");
//Because strtol produces a long, check for overflow
if ( (lnum > INT_MAX) || (lnum < INT_MIN) )
fprintf(stderr, "ERROR: number out of range for INT\n");
//Finally convert the result to a plain int (if that's what you want)
num = (int) lnum;
Hinweis: Wenn Sie sicher sind, dass die Eingabezeichenfolge innerhalb des gültigen int-Bereichs liegt, können Sie sie eliminieren lnum
und werfen Sie einfach die Rückkehr von strtol direkt: num = (int) strtolen(in_str, &end, 10);
Sie können nicht.
atoi
kann Fehler nicht erkennen. Kann das Ergebnis nicht dargestellt werden, atoi
ruft undefiniertes Verhalten auf. Verwenden strtol
Anstatt von atoi
.
Es wird empfohlen, eine sichere CERT-Verschlüsselung zu verwenden strtol
Anstatt von atoi
lesen:
INT06-C. Verwenden Sie strtol() oder eine verwandte Funktion, um ein Zeichenfolgen-Token in eine ganze Zahl umzuwandeln
cplusplus.com ist falsch um
atoi
, erkennt es überhaupt keine Fehler. Vertrauen Sie dieser Seite nicht.– Fred Foo
5. März 2013 um 16:48 Uhr
Die Standards C89, C99 und C11 sagen nichts über den Rückgabewert von aus
atoi()
wenn der richtige Wert außerhalb des Bereichs liegt. Der C++11-Standard sagt sogar noch weniger (er listetatoi
in zwei Tabellen, und das ist alles!). Die Aussagen von cplusplus.com sind im Wesentlichen Wunschdenken und/oder gängige Implementierungen – durch keinen Standard garantiert.– Jonathan Leffler
31. August 2013 um 4:37 Uhr
TL;DR: Verwenden de.cppreference.com/w/cpp/string/byte/atoi stattdessen.
– Kuba hat Monica nicht vergessen
3. September 2015 um 16:17 Uhr