Frage

Ich habe eine große Zahl in einem String gespeichert und versuchen, eine einzelne Ziffer zu extrahieren. Aber was sind die Unterschiede zwischen diesen Anrufen?

#include <iostream>
#include <string>

int main(){
    std::string bigNumber = "93485720394857230";
    char tmp = bigNumber.at(5);
    int digit = atoi(&tmp);
    int digit2 = atoi(&bigNumber.at(5))
    int digit3 = atoi(&bigNumber.at(12));
    std::cout << "digit: " << digit << std::endl;
    std::cout << "digit2: " << digit2 << std::endl;
    std::cout << "digit3: " << digit3 << std::endl;
}

Dies wird die folgende Ausgabe.

  

Ziffer: 7

     

digit2: 2147483647

     

digit3: 57230

Die erste ist das gewünschte Ergebnis. Die zweite scheint mir eine Zufallszahl zu sein, die ich nicht in der Zeichenfolge finden. Das dritte ist das Ende des Strings, aber nicht nur eine einzelne Ziffer, wie ich erwartet hatte, aber bis aus dem 12.-Index bis zum Ende des Strings. Kann jemand die verschiedenen Ausgänge mir das erklären?

EDIT: Wäre dies eine akzeptable Lösung sein

?
char tmp[2] = {bigNumber.at(5), '\0'};
int digit = atoi(tmp);
std::cout << "digit: " << digit << std::endl;
War es hilfreich?

Lösung

Es ist alles mehr oder weniger erklärbar.

int main(){
    std::string bigNumber = "93485720394857230";

Diese Zeile kopiert die einzelnen Zeichen ‚5‘ in die Zeichenvariable. atoi wird dies korrekt konvertieren. atoi erwartet, dass die String-Parameter ein gültiger 0 terminierte String ist. &tmp ist nur ein Zeiger auf die Zeichenvariable - das Verhalten dieser Aufforderung nicht definiert ist, da der Speicher sofort nach dem Zeichen im Speicher unbekannt ist. Um genau zu sein, müßten Sie einen Null-terminierten String erstellen und übergeben, daß in. *

    char tmp = bigNumber.at(5);
    int digit = atoi(&tmp);

Diese Zeile erhält einen Zeiger auf das Zeichen in der Position 5 in der Zeichenkette. Dies geschieht, ein Zeiger in die ursprüngliche große Anzahl String oben zu sein - so der String-Parameter auf atoi sieht aus wie die Zeichenfolge „5720394857230“. atoi wird deutlich oveflow versucht, dies in eine ganze Zahl zu drehen, da keine 32-Bit-Integer wird diese halten.

    int digit2 = atoi(&bigNumber.at(5))

Diese Zeile erhält einen Zeiger in die Zeichenfolge an Position 12. Der Parameter atoi ist die Zeichenfolge "57230". Diese wird in die ganze Zahl umgewandelt 57230 korrekt.

    int digit3 = atoi(&bigNumber.at(12));

...     }

Da Sie C ++ verwenden, es gibt schönere Methoden Zeichenketten in Zahlen zu konvertieren. Eine, die ich teilweise bin, ist die Boost-lexical_cast Bibliothek. Sie würde es so verwenden:

char tmp = bigNumber.at(5);
// convert the character to a string then to an integer
int digit = boost::lexical_cast<int>(std::string(tmp));

// this copies the whole target string at position 5 and then attempts conversion
// if the conversion fails, then a bad_lexical_cast is thrown
int digit2=boost::lexical_cast<int>(std::string(bigNumber.at(5)));

* Streng genommen atoi wird durch die numerischen Zeichen scannen, bis ein nichtnumerisches eines gefunden wird. Es ist eindeutig nicht definiert, wenn sie einen finden würde und was es tun wird, wenn über ungültige Speicherstellen zu lesen.

Andere Tipps

Ich weiß, warum die zweite Nummer wird angezeigt.

Vom atoi Referenz.

  

Wenn der richtige Wert aus dem Bereich der darstellbaren Werte INT_MAX oder INT_MIN zurückgeführt wird.

2147483647 ist INT_MAX

bigNumber.at() keine neue Zeichenfolge mit einem einzelnen Zeichen zurück, aber die Adresse eines Zeichens in der Zeichenkette. So ist der zweite Anruf ist eigentlich:

atoi("720394857230")

, die bewirkt, dass der interne Algorithmus überzulaufen.

Auch der erste Anruf ist sehr gefährlich, da sie auf dem (zufällig) Wert im Speicher (&tmp)+1 abhängig ist.

Sie haben einen String mit zwei Zeichen zuzuordnen, das einzelne Zeichens von bigNumber.at() zum ersten und \0 mit dem zweiten zuweisen und dann atoi() mit der Adresse des temporären String nennen.

Das Argument atoi sollte ein Null-terminierte String sein.

Funktion at gibt Zeiger in der Zeichenfolge verkohlen. Funktion atoi wandelt String in int, nicht nur ein Zeichen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top