Richtige anwendung von std::getline



  • Grüezi Wohl

    Ich habe eine Frage bezüglich (std::cin und std::getline(std::cin, "variable").

    In meinem Programm will ich ein dynamisches array das namen und alter speichert, was auch gut klappt.
    Aber wenn ich std::cin benutze, kann ich ja keine leerzeichen machen, wie z.b. wenn ich als name (Donald Duck) eingeben will.
    ,,
    Benutze ich:

    std::getline(std::cin, name);
    

    , in der (add new human) funktion, steht dann gleich:

    Name: Age:
    

    in der konsolen ausgabe.

    Hier mal der quelltext:

    #include <iostream> // Input Output ( cout cin )
    #include <vector>   // std::vector container
    #include <string>   // std::string type
    
    /* Define the type Human */
    struct Human{
        std::string Name;
        int Age;
    };
    
    /* clear screen - function  */
    void ClearScreen(){
        std::cout << std::string(100, '\n');
    }
    
    /* Add New Human - Function */
    void new_human(std::vector<Human> &human_list){
        std::string name;
        int age;
        std::cout << "Name: ";
        std::getline(std::cin, name); // hier gibt es dann gleich (Name: Age:) aus.
        std::cout << "Age: ";
        std::cin >> age;
        Human tmp_human = {name, age};
        human_list.push_back(tmp_human);
    }
    
    /* Give all humans out - Function */
    void print_human_list(std::vector<Human> &human_list){
        ClearScreen();
        std::cout << "*****{ BEGIN LIST }*****\n\n";
        for(auto human : human_list){
            std::cout << "========================\n";
            std::cout << human.Name << "\n" << human.Age << std::endl;
        }
        std::cout << "-----< END OF LIST >-----\n\n";
    }
    
    /* MAIN FUNCTION  */
    int main(){
        std::vector<Human> human_list;
        char choice;
        for(;;){
            std::cout << "********************\n";
            std::cout << "(N)ew Human\n"
    	          << "(P)rint Human List\n"
    		  << "(Q)uit\n\n: ";
            std::cin >> choice;
    	switch(choice){
                case 'N':
    	    case 'n':
    	        new_human(human_list);
    		break;
    	    case 'P':
    	    case 'p':
    	        print_human_list(human_list);
    		break;
    	    case 'Q':
    	    case 'q':
    	        return 0;
    	    default:
    	        continue;
    		break;
    	}
        }
    }
    

    Ich bin C++ erst am lernen und mein englisch ist auch nicht perfekt, aber will mir angewöhnen alles in english zu halten, damit ich es besser lerne.

    Ich hoffe, jemand kann mir bei meinem Fehler helfen.

    Freundlichst grüsse ich Euch

    Fichtl

    Edit: hmm switch case ist ja ganz verschoben in der main funktion, aber hab den quelltest eig. schön eingerückt.


  • Mod

    Der Operator >> lässt abschließende Trennzeichen im Stream. Trennzeichen für den Operator >> sind alle Arten von Whitespace (daher wurde deine Eingabe vorher immer getrennt), also auch Zeilenumbrüche. getline liest bis zum nächsten Zeilenumbruch (und liest diesen auch mit aus dem Stream aus). Wenn du nun ein getline auf einen Operator>> folgen lässt und die Eingabe für den Operator>> durch einen Zeilenumbruch abgeschlossen wurde, dann ist gleich das erste Zeichen, welches das getline sieht, ein Zeilenumbruch und das getline hört sofort wieder auf.

    Mit ignore kann man nötigenfalls Zeichen einfach überlesen.



  • Vielen lieben dank @SeppJ, echt super.
    Bin froh, das Du es so sauber erklärt hast und nicht einfach eine lösung hingepostet hast. War grad auch ein guter Lern effekt.

    So sieht es jetzt aus:

    /* Add New Human - Function */
    void new_human(std::vector<Human> &human_list){
        std::string name;
        int age;
        std::cin.ignore();  // NEU dank SeppJ :)
        std::cout << "Name: ";
        std::getline(std::cin, name);
        std::cout << "Age: ";
        std::cin >> age;
        Human tmp_human = {name, age};
        human_list.push_back(tmp_human);
    }
    

    und im Terminal, sieht es so aus:

    *****{ BEGIN LIST }*****
    
    ========================
    kerze kirze
    34
    ========================
    batman robin
    56
    ========================
    rofl fafl fifi
    56
    -----< END OF LIST >-----
    
    ********************
    (N)ew Human
    (P)rint Human List
    (Q)uit
    
    :
    

    Edit:
    Die namen sind nicht super, ist ja nur zum lernen und meine Fantasie ist im moment nicht auf der höhe. 😃


Log in to reply