1. std::stoi: Grundidee
Manchmal scheint es, als sei die Zahleneingabe immer std::cin >> x; und fertig. Sobald Sie aber eine ganze Zeile lesen möchten (zum Beispiel „Vorname Nachname“, Adresse, Kommentar oder eine mehrteilige Phrase mit Leerzeichen), wechseln Sie fast automatisch zu std::getline. Und dann tritt die alltägliche Aufgabe auf: „Okay, ich habe die Zeile gelesen, aber da steht doch eine Zahl, wie mache ich daraus einen int?“.
Stellen Sie sich ein Konsolenformular vor: Name — String, Geburtsjahr — scheinbar eine Zahl, aber Sie möchten alles mit getline einlesen, damit die Eingabe einheitlich und ohne Überraschungen ist. Oder der Nutzer tippt den Betrag 1500, Sie wollen ihn zuerst als Text einlesen (String) und danach als Zahl interpretieren. Genau hier kommt std::stoi ins Spiel.
std::stoi ist eine Funktion der Standardbibliothek von C++, die versucht, einen String als Ganzzahl vom Typ int zu interpretieren. Wenn alles gut geht, erhalten Sie einen int und können damit rechnen, vergleichen usw.
Der praktische Schluss ist: stoi ist die Brücke zwischen der Welt des Textes und der Welt der Zahlen.
Minimaler Syntax: String → int
Im Minimalfall sieht stoi so aus: man hat ein std::string und erhält einen int. Wichtig ist, <string> zu includen, denn sowohl std::string als auch std::stoi befinden sich dort.
#include <iostream>
#include <string>
int main() {
std::string text = "42";
int value = std::stoi(text);
std::cout << value << '\n'; // 42
}
In diesem Beispiel passt der String "42" perfekt zur Umwandlung in eine Zahl. Deshalb arbeitet std::stoi „ohne Theater“: Sie erhalten die 42.
Einbau von stoi in die „live“ Eingabe via getline
Der nächste Schritt ist das, wofür man stoi meist braucht: eine Zeile einlesen (meist mit getline) und in eine Zahl verwandeln.
Hier ist es wichtig, nicht zu hetzen. Wir lesen die Zeile als Text und sagen erst danach: „Jetzt versuchen wir, sie in eine Zahl zu verwandeln“.
#include <iostream>
#include <string>
int main() {
std::string line;
std::getline(std::cin, line);
int n = std::stoi(line);
std::cout << "n = " << n << '\n'; // zum Beispiel: n = 15
}
Beachten Sie den psychologischen Punkt: das Programm nimmt die Eingabe zunächst „höflich“ im sicheren Format (String) entgegen und macht dann den Interpretationsschritt. Das ist oft bequemer, als sofort einen int einzulesen, besonders wenn das Eingabeformat komplexer ist als „eine einzige Zahl ohne Leerzeichen“.
3. Praktisches Beispiel: Mini-Formular
Fahren wir mit einer hypothetischen Lernanwendung fort — einem Konsolenformular. Zuvor konnten Sie Fragen mit std::cout ausgeben, den Namen mit getline lesen, und jetzt fügen wir das Einlesen einer Zahl als String und die Konvertierung via stoi hinzu.
Die Idee ist einfach: wir fragen nach dem Namen (String), nach dem Geburtsjahr (String), wandeln das Geburtsjahr in einen int um und berechnen das Alter relativ zu einem festen Jahr (nehmen wir 2026 — nur als Beispiel; ja, das Programm hat noch keine echte Kalenderanbindung).
#include <iostream>
#include <string>
int main() {
std::string fullName;
std::string birthYearText;
std::cout << "Geben Sie Vor- und Nachname ein: ";
std::getline(std::cin, fullName);
std::cout << "Geben Sie das Geburtsjahr ein (z. B. 2005): ";
std::getline(std::cin, birthYearText);
int birthYear = std::stoi(birthYearText);
int age = 2026 - birthYear;
std::cout << "Hallo, " << fullName << "!\n";
std::cout << "Sie sind ungefähr " << age << " Jahre alt.\n";
}
Beachten Sie, wie sauber wir ohne Vermischung von >> und getline gearbeitet haben: alles wird über getline gelesen, und das macht das Eingabeverhalten vorhersehbar. Als Anfänger ist „Vorhersehbarkeit“ meist wichtiger als „ich kann die Zahl in einem Schritt mit cin >> einlesen“.
4. Verhalten von stoi: was sie „verzeiht“ und wo sie tückisch ist
Führende Leerzeichen und Vorzeichen
Benutzer tippen nicht immer perfekt. Zum Beispiel fügen sie führende Leerzeichen ein. Die gute Nachricht: std::stoi kann führende Leerzeichen überspringen. Die schlechte Nachricht: das kann den Eindruck erwecken, sie verzeihe alles — und das ist eine gefährliche Illusion.
#include <iostream>
#include <string>
int main() {
std::string text = " 15";
int value = std::stoi(text);
std::cout << value << '\n'; // 15
}
Leerzeichen am Anfang haben nicht gestört. Das ist praktisch, aber zugleich ein Hinweis: stoi ist kein strenger Parser, sondern eher ein Algorithmus nach dem Motto „ich versuche zu erraten, was Sie meinten“.
Teilweise Umwandlung: Zahl am Anfang, Rest Müll
Hier beginnt das Interessante (und Tückische). Ein String kann eine Zahl am Anfang enthalten und danach Müll. Und std::stoi nimmt oft die Zahl am Anfang und stoppt am ersten ungeeigneten Zeichen.
Das heißt, der String "12kg" kann durchaus zur Zahl 12 werden.
#include <iostream>
#include <string>
int main() {
std::string text = "12kg";
int value = std::stoi(text);
std::cout << value << '\n'; // 12
}
Warum ist das wichtig? Weil semantisch "12kg" keine reine Zahl ist, sondern „Zahl + Einheit“. Manchmal ist dieses Verhalten nützlich (wenn das Format genau so ist: Zahl am Anfang, dann Suffix). Häufiger erwartet der Anfänger jedoch Striktheit: „Wenn das nicht eine saubere Zahl ist, ist das ein Fehler“. Und stoi kann stillschweigend zustimmen und Ihnen eine halbe Wahrheit liefern.
Zur Veranschaulichung:
| Eingabe-String | Was Sie erwarten könnten | Was stoi oft macht |
|---|---|---|
|
|
|
|
Fehler oder 42 | |
|
Fehler | |
|
Fehler | Laufzeitfehler (häufig) |
|
Fehler | Laufzeitfehler (häufig) |
Das Wort „häufig“ dient hier nicht zur Ausflucht, sondern als Erinnerung: das genaue Verhalten im Detail ist Spezifikationssache und erfordert bewusstes Fehlerhandling. Wir sind im Moment auf dem Niveau „Ich verstehe die Idee und die Grenzen“.
5. Grenzen von stoi: warum Laufzeitfehler möglich sind
Wichtiger Punkt: std::stoi ist keine Magie, sondern eine Funktion, die scheitern kann.
Wenn der String nicht wie eine Zahl aussieht (zum Beispiel "hello", ein leerer String "" oder ein numerischer Wert, der zu groß für int ist), kann beim Aufruf von stoi ein Laufzeitfehler auftreten. Subjektiv wirkt das so: Sie starten das Programm, geben etwas „Falsches“ ein, und es beendet sich abrupt (manchmal mit einer Fehlermeldung, manchmal einfach mit „Runtime error“).
Hier ist es wichtig, nicht in Extreme zu verfallen.
Das erste Extrem ist Panik: „Alles, stoi ist unbrauchbar“. Das ist nicht so — man kann sie verwenden, man muss nur den Rahmen verstehen: in dieser Vorlesung zeigen wir stoi als Demonstration der Umwandlung bei korrekter Eingabe.
Das zweite Extrem ist Selbstüberschätzung: „Wenn sie manchmal sogar mit "12kg" funktioniert, dann ist sie schlau und versteht den Sinn“. Nein. Sie „versteht“ nicht; sie führt ihr Algorithmus aus, und wenn das Eingabeformat außerhalb der Erwartungen liegt, bekommen Sie einen Laufzeitfehler.
Besonders oft geraten Anfänger in Schwierigkeiten, wenn nach std::getline eine leere Zeile vorliegt (zum Beispiel als Restzeichenfolge '\n' nach einer >>-Operation), und dann rufen sie stoi mit diesem leeren String auf. Ein leerer String ist keine Zahl, und stoi stürzt dann meistens ab.
6. Verbindung von getline und dem Operator >>
Jetzt eine kurze Brücke zum Thema „Restzeichen '\n'“, ohne es komplett zu wiederholen. Wir zeigen, warum das gerade für stoi wichtig ist.
Wenn Sie zuerst eine Zahl mit std::cin >> einlesen und anschließend eine Zeile mit getline, dann liest das erste getline oft eine leere Zeile. Und wenn Sie diese leere Zeile an stoi übergeben, ist das sehr traurig.
Deshalb sollten Sie in gemischten Eingabeformaten ein „Übergangs-getline“ verwenden, um das Rest-'\n' zu konsumieren.
#include <iostream>
#include <string>
int main() {
int a = 0;
std::string dummy;
std::string numberLine;
std::cin >> a;
std::getline(std::cin, dummy); // Rest '\n' aufsaugen
std::getline(std::cin, numberLine); // Zeile einlesen
int b = std::stoi(numberLine);
std::cout << (a + b) << '\n';
}
Auf unserem Niveau ist das eine Hygieneregel: wenn Sie vorhaben, einen String mit einer Zahl per stoi zu konvertieren, stellen Sie zuerst sicher, dass Sie wirklich eine nicht-leere und nicht-zufällige Zeile gelesen haben.
7. Konvertierung vs. Validierung: nicht verwechseln
Es ist sehr nützlich, die beiden Begriffe im Voraus zu trennen.
Konvertierung — das heißt: „Ich habe bereits einen korrekten String mit einer Zahl, verwandle ihn in einen int“. Genau das macht stoi in unserer heutigen Verwendung.
Validierung — das heißt: „Prüfe, ob der String wirklich eine gültige Zahl ist, und behandle Fehler sauber“. Das ist eine gesonderte ingenieurmäßige Aufgabe, die entweder eine aufwendigere Eingabe, Fehlerbehandlung oder andere Werkzeuge der Standardbibliothek erfordert. Darauf gehen wir hier noch nicht ein: nicht weil es verboten wäre, sondern weil der Kurs eine Reihenfolge hat und wir die Anfänger nicht in ein Marathonproblem stürzen wollen.
Die ehrliche Abgrenzung der Vorlesung lautet daher: std::stoi dient hier zur Demonstration der Mechanik „String → int“ und zum Kennenlernen der Grenzen.
8. Typische Fehler bei der Arbeit mit std::stoi
Fehler Nr. 1: stoi als „Korrektheitsprüfung“ ansehen.
Anfänger denken oft: „Wenn stoi eine Zahl zurückgibt, ist der String korrekt“. Aber der String "12kg" kann die 12 liefern, und das Programm läuft weiter, als sei alles in Ordnung. Das ist keine Validierung, das ist das Extrahieren einer Zahl vom Anfang des Strings.
Fehler Nr. 2: eine leere Zeile an stoi übergeben nach getline.
Eine leere Zeile ist ein normaler Ergebniswert von getline (der Nutzer hat Enter gedrückt oder Sie haben versehentlich das Rest-'\n' gelesen). Für stoi bedeutet eine leere Zeile in der Regel einen Laufzeitfehler. „Zeile gelesen“ ist nicht gleich „Zeile mit Zahl gelesen“.
Fehler Nr. 3: vergessen, dass stoi mit int arbeitet, und int nicht unendlich ist.
Selbst wenn der String numerisch aussieht, kann er für den Typ int zu groß sein. Dann kann stoi ebenfalls einen Laufzeitfehler auslösen. Merken Sie sich: Typen haben Bereiche, und die Eingabe kann „zu groß“ sein.
Fehler Nr. 4: std::cin >> und std::getline vermischen ohne Übergangszeile und anschließend stoi die Schuld geben.
Es ist leicht, Ursache und Wirkung zu vertauschen: das Programm stürzt bei stoi ab, aber die wahre Ursache ist, dass getline eine leere Zeile gelesen hat, weil noch ein Rest-'\n' vorhanden war. Dann scheint stoi „kaputt“, obwohl die Eingabelogik das Problem ist.
Fehler Nr. 5: vergessen, <string> zu includen.
Manchmal kompiliert der Code in einer Umgebung, aber nicht in einer anderen, und der Student vermutet einen Compiler-Verschwörung. In Wirklichkeit leben std::string und std::stoi im Header <string>, und es ist besser, diesen explizit zu includen, damit der Code portabel und klar ist.
GO TO FULL VERSION