std::getline() wirft out_of_range exception



  • Hey 🙂

    Ich möchte gerne eine ganze Zeile einer Nutzer Eingabe über die Konsole lesen.
    Folgende beiden Code Varianten werfen jedoch leider eine out_of_range exception, weil bereits einfach in die "toVector" Funktion gegangen wird, ohne, dass vom Nutzer in der Konsole eine Eingabe gelesen wird:

    1. Variante:
    std::string input {};
    input.resize(200);
    std::cout << "What would you like to do?" << std::endl;
    std::getline(std::cin, input);
    UserInputExecutor::toVector(input, this->executionChainParameter.get()->userInput);
    
    1. Variante:
    char input[200];
    std::cout << "What would you like to do?" << std::endl;
    std::cin.getline(input, sizeof(input));
    UserInputExecutor::toVector(input, this->executionChainParameter.get()->userInput);
    

    Ausgabe auf der Konsole:

    What would you like to do?
    terminate called after throwing an instance of 'std::out_of_range'
      what():  vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)
    

    Woran kann das liegen? Die Beispiele sind im Internet alle ähnlich und sollen angeblich funktionieren.


  • Mod

    Das wird wohl deine Zeile 5 bzw. 4 sein, von der wir nicht wissen können, was dahinter steckt.

    Das resizen in der 1. Variante kannst du dir sparen. Das ist ja gerade das nette an std::string, dass man sich um so etwas nicht selber kümmern muss. Das ist aus dem gleichen Grund auch die Variante, die du bevorzugen solltest.



  • Danke für die Antwort 🙂

    Ja das resizen habe ich auch nicht mehr drin.
    Es lag tatsächlich daran, dass ich std::cin vorher schon benutzt habe.

    Mit

    std::cin.clear();
    std::cin.ignore(10000,'\n');
    

    geht es nun. Vielen Dank!


  • Mod

    Das sollte deinen Fehler aber eigentlich nicht erklären. Das sollte bloß bewirken, dass deine Eingabe vielleicht was anderes enthält als du denkst.

    Was hier wahrscheinlicher klingt ist, dass dein getline ganz fehl schlägt, weil dein cin vielleicht noch in einem Fehlerzustand ist von einer vorherigen Aktion. Kommt deine Zeile 5/4 mit leeren Eingaben zurecht? Allgemein könntest und solltest du den Erfolg von Nutzereingaben prüfen, z.B.

    if (!std::getline(std::cin, input))
       // Fehler
    

    Die Zahl 10000 in deinem ignore wirkt magisch ist aber wahrscheinlich nicht was du willst. Üblichere Zahlen wären entweder 1 oder std::numeric_limits<std::streamsize>::max(). Letzteres ist nämlich wirklich magisch, weil es vom ignore als "unendlich" interpretiert wird.


Log in to reply