Problem mit getline!


  • 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



  • @RBS2
    Ich habe es auch grade gesehen und geändert 🙂
    Aber ich habe noch was anderes:
    c:\c++ programmierung\lernen\lernen\lernen.cpp(15): warning C26495: Variable 'Kunde::Liefernummer' is uninitialized. Always initialize a member variable (type.6).

    Wäre cool wenn ihr mich da auch weiterhelfen könntet

    LG Paul



  • Der Compiler sagt dir doch schon, was du tun sollst... initialisier´ die Member Variable in Zeile 15:

    struct Kunde
    {
       string Name;
       string Lieferadresse;
       int Liefernummer = 0;
    };
    

    Da hätte man auch von alleine drauf kommen können.



  • @DocShoe
    Mhhhh... du hast recht..
    Sorry aber jetzt geht es 🙂



  • Eigentlich wars so gemeint, dass Du das goto mit einer Schleife ersetzen sollst, und nicht mit sechs ..

    Vergleich mal Deinen Programmablauf mit dem von @wob skizzierten und überlege Dir, welcher verständlicher ist...

    Du hast zwar ein paar Punkte umgesetzt, aber es wurden auch viele Dinge genannt, die Du irgendwie ignoriert hast. Fazit: Gutes Lehrbuch besorgen und damit lernen, sonst wirds schwierig. Gut gemeinter Hinweis.

    Edit: Ach ne, das goto ist ja immernoch da.... Mein Fehler m(


Anmelden zum Antworten