Ich versuche herauszufinden, ob es eine alternative Möglichkeit gibt, einen String in eine Ganzzahl in C umzuwandeln.
Ich strukturiere regelmäßig Folgendes in meinem Code.
char s[] = "45";
int num = atoi(s);
Gibt es einen besseren oder einen anderen Weg?
Antworten:
Es gibt
strtol
welche IMO besser ist. Auch ich habe eine Vorliebe dafürstrtonum
, also benutze es, wenn du es hast (aber denk daran, es ist nicht tragbar):BEARBEITEN
Das könnte Sie auch interessieren
strtoumax
undstrtoimax
welche Standardfunktionen in C99 sind. Zum Beispiel könnte man sagen:Wie auch immer, halte dich fern von
atoi
:quelle
strtonum
? Ich#<stdlib.h>
. Sie können jedoch die Standardalternative verwendenstrtoumax
.Robuste C89-
strtol
basierte LösungMit:
atoi
Familie)strtol
(z. B. kein führendes Leerzeichen oder nachfolgende Papierkorbzeichen)GitHub stromaufwärts .
Basierend auf: https://stackoverflow.com/a/6154614/895245
quelle
str2int()
. Pedantisch: verwendenisspace((unsigned char) s[0])
.(unsigned char)
Besetzung einen Unterschied machen könnte?l > INT_MAX
undl < INT_MIN
ist ein sinnloser Ganzzahlvergleich, da jedes Ergebnis immer falsch ist. Was passiert, wenn ich sie änderel >= INT_MAX
undl <= INT_MIN
die Warnungen lösche? Auf ARM C sind long und int 32-Bit-signierte Basisdatentypen in ARM C und C ++l >= INT_MAX
falsche Funktionen zu erhalten: Beispiel für die RückgabeSTR2INT_OVERFLOW
mit Eingabe"32767"
und 16-Bitint
. Verwenden Sie eine bedingte Kompilierung. Beispiel .if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX)) return STR2INT_OVERFLOW;
wäre besser , alsif (l > INT_MAX || (errno == ERANGE && l == LONG_MAX)) { errno = ERANGE; return STR2INT_OVERFLOW;}
zu verwenden , damit Code Aufruferrno
aufint
Out-of-Bereich. Gleiches gilt fürif (l < INT_MIN...
.Verwenden Sie keine Funktionen aus der
ato...
Gruppe. Diese sind kaputt und praktisch nutzlos. Eine mäßig bessere Lösung wäre die Verwendungsscanf
, obwohl sie auch nicht perfekt ist.Um eine Zeichenfolge in eine Ganzzahl umzuwandeln, sollten Funktionen aus der
strto...
Gruppe verwendet werden. In Ihrem speziellen Fall wäre esstrtol
Funktion.quelle
sscanf
hat tatsächlich ein undefiniertes Verhalten, wenn versucht wird, eine Zahl außerhalb des Bereichs seines Typs zu konvertieren (z. B.sscanf("999999999999999999999", "%d", &n)
).atoi
bietet kein aussagekräftiges Erfolgs- / Fehler-Feedback und weist ein undefiniertes Verhalten beim Überlauf auf.sscanf
Bietet eine Art Erfolgs- / Fehler-Feedback (der Rückgabewert, wodurch es "mäßig besser" wird), weist jedoch immer noch ein undefiniertes Verhalten beim Überlauf auf. Nurstrtol
ist eine tragfähige Lösung.sscanf
. (Obwohl ich gestehe, dass ich manchmal benutzeatoi
, normalerweise für Programme, von denen ich nicht erwarte, dass sie länger als 10 Minuten überleben, bevor ich die Quelle lösche.)Sie können ein wenig atoi () zum Spaß codieren:
Sie können es auch rekursiv machen, was in 3 Zeilen alt sein kann =)
quelle
code
((* str) - '0')code
"----1"
2) Hat undefiniertes Verhalten mitint
Überlauf, wenn das Ergebnis sein sollteINT_MIN
. Betrachten Siemy_getnbr("-2147483648")
Ich wollte nur eine Lösung für unsigned long teilen.
quelle
const char *
.48
bedeutet das? Gehen Sie davon aus, dass dies der Wert ist, unter'0'
dem der Code ausgeführt wird? Bitte geben Sie der Welt keine so breiten Annahmen!'0'
Sie es einfach so, wie Sie es sollten.quelle
Sie können immer Ihre eigenen rollen!
Dies wird tun, was Sie wollen, ohne Unordnung.
quelle
strto...
Funktionsfamilie nicht zu verwenden . Sie sind tragbar und deutlich besser.0x2d, 0x30
statt'-', '0'
. Erlaubt kein'+'
Zeichen. Warum(int)
einwerfen(int)strlen(snum)
? UB wenn Eingang ist""
. UB, wenn das ErgebnisINT_MIN
auf einenint
Überlauf mitaccum += (snum[strIdx] - 0x30) * pow(10, idx);
Diese Funktion wird Ihnen helfen
Ref: http://amscata.blogspot.com/2013/09/strnumstr-version-2.html
quelle
atoi
und bei Freunden ist, dass es bei Überlauf undefiniertes Verhalten gibt. Ihre Funktion prüft dies nicht.strtol
und Freunde tun.Ok, ich hatte das gleiche Problem. Ich habe diese Lösung gefunden. Sie hat bei mir am besten funktioniert. Ich habe atoi () ausprobiert, aber bei mir nicht gut funktioniert. Also hier ist meine Lösung:
quelle
quelle
nInt = (nInt *= 10) + ((int) snum[index] - 48);
vs.nInt = nInt*10 + snum[index] - '0';
if(!nInt)
nicht benötigt.In C ++ können Sie eine solche Funktion verwenden:
Dies kann Ihnen helfen, eine beliebige Zeichenfolge in einen beliebigen Typ wie float, int, double ... zu konvertieren.
quelle
Ja, Sie können die Ganzzahl direkt speichern:
Wenn Sie eine Zeichenfolge analysieren müssen
atoi
oderstrol
den Wettbewerb "Kürzeste Menge an Code" gewinnen möchten.quelle
strtol()
tatsächlich eine ganze Menge Code. Es kann zurückgegeben werdenLONG_MIN
oderLONG_MAX
entweder, wenn dies der tatsächlich konvertierte Wert ist oder wenn ein Unter- oder Überlauf vorliegt, und es kann 0 zurückgeben, entweder wenn dies der tatsächliche Wert ist oder wenn keine zu konvertierende Zahl vorhanden war. Sie müssenerrno = 0
vor dem Anruf einstellen und die überprüfenendptr
.