Problem mit getline!



  • Hey ich bin Paul 16 Jahre alt und mache eine Ausbildung als Fachinformatiker.
    Ich fange gerade erst an mit dem Programmieren und sollte mit getline Zeilen einlesen.

    Nun habe ich folgendes Problem:
    Wenn ich das Programm neu starten will, kann ich in die erste Variable nichts mehr reinschreiben, sondern sie wird einfach übersprungen.

    Ich bitte um Hilfe!

    Code:

    #include "pch.h"
    #include <iostream>
    #include <conio.h>
    #include <iomanip>
    #include <ctime>
    #include <cstdlib>
    #include <string>
    #include <string.h>
    #include <limits>
    using namespace std;
    
    namespace Umlaut
    {
    	const unsigned char AE = static_cast<unsigned char>(142);
    	const unsigned char ae = static_cast<unsigned char>(132);
    	const unsigned char OE = static_cast<unsigned char>(153);
    	const unsigned char oe = static_cast<unsigned char>(148);
    	const unsigned char UE = static_cast<unsigned char>(154);
    	const unsigned char ue = static_cast<unsigned char>(129);
    	const unsigned char ss = static_cast<unsigned char>(225);
    }
    
    struct Kunde
    {
    	string Name;
    	string Lieferadresse;
    	int Liefernummer;
    	double Umsatz;
    	char Hausnummer[10];
    };
    
    
    
    int main()
    {
    	char Neustart;
    	int Zufallszahl;
    	string LA;
    	string NA;
    	
    	
    	struct Kunde K1;
    
    	anfang:
    		
    		//Eingabe der Daten
    		//cout << K1.Name << endl; 
    		//cout << " " << endl;
    		cout << "Bitte geben sie Ihren Namen ein!" << endl;
    		getline(cin,NA);
    		cout << "Bitte geben sie Ihre Lieferadresse ein!" << endl;
    		getline(cin,LA);
    		K1.Lieferadresse = LA;
    		//K1.Name = NA;
    		cout << K1.Name << endl;
    		
    
    		//Zufalls Zahl für die Liefernummer
    		srand((unsigned)time(NULL));
    		Zufallszahl = rand() % 10000;
    		K1.Liefernummer = Zufallszahl;
    
    		cout << setfill('-') << setw(133) << endl;
    		cout << "\nLiefername: " << K1.Name << " " << "          Lieferadresse: " << K1.Lieferadresse << " " << "           Liefernummer: " << K1.Liefernummer;
    		cout << setfill('-') << setw(121) << endl;
    		cout << " " << endl;
    
    		cout << "Wollen sie das Programm neustarten ? (Y/N)" << endl;
    		cin >> Neustart;
    		//cout << Neustart;
    		if (Neustart == 'Y','y')
    		{
    			cout << K1.Name << endl;
    			goto anfang;
    		}
    	
    
    
    	return 0;
    
    }
    


  • hast du mal mit dem debugger geguckt, was da in den string reingeschrieben wird?



  • Dies steht bei mir im Debugger 😞

    Lernen.exe" (Win32): "C:\Windows\SysWOW64\version.dll" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden.
    Der Thread 0x2a1c hat mit Code 0 (0x0) geendet.
    Der Thread 0x31b8 hat mit Code 0 (0x0) geendet.
    Der Thread 0x351c hat mit Code 0 (0x0) geendet.
    Der Thread 0x3580 hat mit Code 0 (0x0) geendet.
    Das Programm "[17536] Lernen.exe" wurde mit Code 0 (0x0) beendet.



  • wenn du einen haltepunkt setzt, kannst du dir meine ich ansehen, was da in dem string drin ist.


  • Gesperrt

    @hiyuck sagte in Problem mit getline!:

    cin >> Neustart;

    Mach daraus mal:

    cin >> Neustart; cin.ignore(INT_MAX,'\n');
    

    Die Zeile: if (Neustart == 'Y','y')
    macht bestimmt auch nicht was du denkst. 🐱


  • Mod

    @RBS2 : Erklär doch mal bitte, wieso gerade INT_MAX.


  • Gesperrt

    @SeppJ sagte in Problem mit getline!:

    @RBS2 : Erklär doch mal bitte, wieso gerade INT_MAX.

    http://www.cplusplus.com/reference/istream/istream/ignore/
    'Maximum number of characters to ignore.'
    INT_MAX = alles, was noch im Stream hängt.

    numeric_limits.max() ginge auch: http://www.cplusplus.com/reference/limits/numeric_limits/


  • Mod

    numeric_limits<streamsize>::max() spielt eine definitorische Rolle, INT_MAX nicht. Schau mal auf der Website, die du verlinkt hast.


  • Gesperrt

    @Columbo sagte in Problem mit getline!:

    numeric_limits<streamsize>::max() spielt eine definitorische Rolle, INT_MAX nicht.

    Kann es denn vorkommen, dass numeric_limits<streamsize>::max() != INT_MAX ist?


  • Gesperrt

    @Columbo sagte in Problem mit getline!:

    numeric_limits<streamsize>::max() spielt eine definitorische Rolle, INT_MAX nicht. Schau mal auf der Website, die du verlinkt hast.

    Hier ist numeric_limits<streamsize>::max() größer als numeric_limits<int>::max() ...
    --> https://en.cppreference.com/w/cpp/types/numeric_limits/max


  • Mod

    @RBS2 sagte in Problem mit getline!:

    @Columbo sagte in Problem mit getline!:

    numeric_limits<streamsize>::max() spielt eine definitorische Rolle, INT_MAX nicht.

    Kann es denn vorkommen, dass numeric_limits<streamsize>::max() != INT_MAX ist?

    Und wenn nicht? Warum einen Ausdruck verwenden, der kein Idiom ist, und nicht vom Standard explizit fuer diesen Zweck abgesegnet wird? Mach dir doch nicht das Leben schwer.



  • Keiner spricht an, dass das goto total unnötig ist und i. A. Programme schwerer zu verstehen macht?

    Wobei ich hab im LLVM Lexer Code auch schon goto gesehen, also ok... vielleicht übertreibe ich ja auch ?!



  • @HarteWare Du hast sicher recht. Vor allem als Anfänger sollte man so tun, als würde goto gar nicht existieren. Und als erfahrener Programmierer sollte man goto gut verstecken, sodass man es möglichst nicht so schnell wieder findet 🙂

    Es stellen sich auch noch diverse andere Fragen. Warum zum Beispiel werden alle möglichen Header includet? Warum ist Hausnummer ein "char[10]"-Array statt std::string? Überhaupt, warum gibt es ein Feld "Lieferanschrift" und ein zusätzliches Feld "Hausnummer"? Warum ist eine "Liefernummer" die Eigenschaft eines Kunden? Warum wird die Kunden-Variable mit "struct Kunde" statt nur mit "Kunde" deklariert? Warum wird srand innerhalb der goto-Schleife aufgerufen? Und so weiter, und so fort. Da fällt das goto kaum ins Gewicht.



  • @RBS2 sagte in Problem mit getline!:

    cin.ignore(INT_MAX,'\n');

    Hey @RBS2 🙂
    Danke für deine Lösung es klappt jetzt super!



  • @wob
    Ja du hast recht ich habe jetzt den Code nochmal geändert.
    Sieht das besser aus ?

    #include "pch.h"
    #include <iostream>
    #include <string>
    #include <iomanip>
    #include <ctime>
    #include <stdlib.h>
    using namespace std;
    
    //Struktur
    struct Kunde
    {
    	string Name;
    	string Lieferadresse;
    	int Liefernummer;
    };
    
    
    
    int main()
    {
    	//Variablen
    	int Var1;
    	int ZZ;
    	int Var2 = 0;
    
    
    	struct Kunde K1;
    
    anfang:
    
    	if (Var2 == 1)
    	{
    		system("cls");
    	}
    
    	//Eingabe durch User
    	cout << "Bitte geben sie ihren Namen ein!" << endl;
    	getline(cin, K1.Name);
    	cout << "Bitte geben sie nun ihre Lieferadresse ein!" << endl;
    	getline(cin, K1.Lieferadresse);
    	cout << "Haben sie eine Liefernummer ? (0=No/1=Yes)" << endl;
    	while (!(cin >> Var1))
    	{
    		// Fehler...
    		cin.clear();
    		cin.ignore(numeric_limits<streamsize>::max(), '\n');
    		cout << "Bitte geben sie nur Zahlen ein!" << endl;
    	}
    
    	//Liefernummer
    	if (Var1 == 0)
    	{
    		srand((unsigned)time(NULL));
    		ZZ = rand() % 10000;
    		K1.Liefernummer = ZZ;
    	}
    	else if (Var1 == 1)
    	{
    		cout << "Bitte geben sie ihre Liefernummer ein!" << endl;
    		while (!(cin >> K1.Liefernummer))
    		{
    			// Fehler...
    			cin.clear();
    			cin.ignore(numeric_limits<streamsize>::max(), '\n');
    			cout << "Bitte geben sie nur Zahlen ein!" << endl;
    		}
    	}
    
    	//Ausgabe
    	cout << "-----------------------------------------------------------------------------------------------------------------------" << endl;
    	cout << setw(5) << "Name: " << K1.Name << setw(30) << "Lieferadresse: " << K1.Lieferadresse << setw(30) << "Liefernummer: " << K1.Liefernummer << endl;
    	cout << "-----------------------------------------------------------------------------------------------------------------------" << endl;
    
    	cout << "\nMöchten sie das Programm neustarten (0=No/1=Yes)" << endl;
    	cin >> Var2; cin.ignore(INT_MAX, '\n');
    	if (Var2 == 1)
    	{
    		goto anfang;
    	}
    
    	return 0;
    
    }
    


  • @hiyuck sagte in Problem mit getline!:

    Sieht das besser aus ?

    Du hast immer noch

    • nichtssagende Variablennamen
    • goto
    • srand in eine Schleife (die mit dem goto)
    • Sprachmischmasch in der Nutzerführung (im Programmcode ist mir das egal)


  • @hiyuck Beachte DirkBs Kommentare.

    Allgemein könnte dein main ohne goto so aussehen:

    bool liesNochmalAusfuehren() {
        std::cout << "\nMöchten sie das Programm neustarten  (n=nein/j=ja)\n";
        std::string runAgain;
        std::cin >> runAgain;
        return runAgain == "j"; // du könntest auch noch auf falsche Eingabe testen
    }
    
    Kunde kundeEinlesen() {
        Kunde k;
        cout << ...
        cin >> k.name;
        ....
        return k;
    }
    
    void kundeAusgeben(const Kunde& kunde) {
        std::cout << "-----------------------------------------------------------------------------------------------------------------------\n";
    	      << setw(5) << "Name: " << kunde.Name << ...
        ...
    }
    
    int main() {
        do {
            Kunde kunde = kundeEinlesen();
            kundeAusgeben(kunde);
        } while (liesNochmalAusfuehren());
    }
    

    Damit hättest du etwas Struktur drin und könntest die Einlese- und Ausgabefunktion wiederverwerten.

    Du kannst auch das ausgeben zu einer Funktion von Kunde machen, sodass du kunde.ausgeben() schreibst. Und danach kannst du dir anschauen, wie man den Operator<< überladen kann, sodass du std::cout << kunde << '\n'; schreiben könntest.


  • Gesperrt

    @hiyuck sagte in Problem mit getline!:

    @RBS2 sagte in Problem mit getline!:

    cin.ignore(INT_MAX,'\n');

    Hey @RBS2 🙂
    Danke für deine Lösung es klappt jetzt super!

    Gern geschen, Bro. Aber beachte bitte auch die Ergänzungen von Detective Columbo. 🐱



  • So ich habe jetzt mein Code noch einmal bearbeitet nach euren Vorschlägen 🙂
    Vielen Dank an euch alle!

    #include "pch.h"
    #include <iostream>
    #include <string>
    #include <iomanip>
    #include <ctime>
    #include <stdlib.h>
    using namespace std;
    
    //Struktur
    struct Kunde
    {
    	string Name;
    	string Lieferadresse;
    	int Liefernummer;
    };
    
    const unsigned char AE = static_cast<unsigned char>(142);
    const unsigned char ae = static_cast<unsigned char>(132);
    const unsigned char OE = static_cast<unsigned char>(153);
    const unsigned char oe = static_cast<unsigned char>(148);
    const unsigned char UE = static_cast<unsigned char>(154);
    const unsigned char ue = static_cast<unsigned char>(129);
    const unsigned char ss = static_cast<unsigned char>(225);
    
    
    
    int main()
    {
    	//Variablen 
    	//LN= Liefernumemr ; ZZ= Zufallszahl
    	int LN = 0;
    	int ZZ;
    	int Neustart = 0;
    
    
    	struct Kunde K1;
    	srand((unsigned)time(NULL));
    
    
    	do
    	{
    			if (Neustart == 1)
    			{
    				system("cls");
    			}
    	
    			//Eingabe durch User
    			cout << "Bitte geben sie ihren vollen Namen ein!" << endl;
    			getline(cin, K1.Name);
    			cout << "Bitte geben sie nun ihre komplette Lieferadresse ein!" << endl;
    			getline(cin, K1.Lieferadresse);
    			do
    			{
    				cout << "Haben sie eine Liefernummer ? (0=No/1=Yes)" << endl;
    				while (!(cin >> LN))
    				{
    					// Fehler...
    					cin.clear();
    					cin.ignore(numeric_limits<streamsize>::max(), '\n');
    					cout << "Bitte geben sie nur Zahlen ein!" << endl;
    				}
    					if (LN > 1)
    					{
    						cout << "Bitte geben sie f" << ue << "r Ja(1) und f" << ue << "r Nein(0) ein!" << endl;
    					}
    			} while (LN > 1);
    
    			//Liefernummer
    			if (LN == 0)
    			{
    				ZZ = rand() % 10000;
    				K1.Liefernummer = ZZ;
    			}
    			else if (LN == 1)
    			{
    				cout << "Bitte geben sie ihre komplette Liefernummer ein!" << endl;
    				while (!(cin >> K1.Liefernummer))
    				{
    					// Fehler...
    					cin.clear();
    					cin.ignore(numeric_limits<streamsize>::max(), '\n');
    					cout << "Bitte geben sie nur Zahlen ein!" << endl;
    				}
    			}
    
    			//Ausgabe
    			cout << "-----------------------------------------------------------------------------------------------------------------------" << endl;
    			cout << setw(5) << "Name: " << K1.Name << setw(30) << "Lieferadresse: " << K1.Lieferadresse << setw(30) << "Liefernummer: " << K1.Liefernummer << endl;
    			cout << "-----------------------------------------------------------------------------------------------------------------------" << endl;
    
    			do
    			{
    				cout << "\nMöchten sie das Programm neustarten (0=No/1=Yes)" << endl;
    				while (!(cin >> Neustart))
    				{
    					// Fehler...
    					cin.clear();
    					cin.ignore(numeric_limits<streamsize>::max(), '\n');
    					cout << "Bitte geben sie nur Zahlen ein!" << endl;
    				}cin.ignore(INT_MAX, '\n');
    
    				if (Neustart != 0, 1)
    				{
    					cout << "Bitte geben sie f" << ue << "r Ja(1) und f" << ue << "r Nein(0) ein!" << endl;
    				}
    			} while (Neustart > 1);
    
    
    
    
    
    	} while (Neustart == 1);
    	return 0;
    
    }
    

  • Gesperrt

    @hiyuck sagte in Problem mit getline!:

    if (Neustart != 0, 1)

    Fragwürdiger Code in Zeile 102 ...

    Der Komma-Operator verwirft den/die ersten Operanden, so du denn schreiben kannst "if (Neustart != 1)", was das Gleiche ist. Siehe: https://en.wikipedia.org/wiki/Comma_operator


Anmelden zum Antworten