Erneute Abfrage der einzelnen Variablen funktioniert nicht.



  • Hallo, ich bin neu hier im Forum (also verurteilt mich nicht, wenn ich evtl. eine Frage stelle, die bereits irgendwo beantwortet ist, bzw. mein Beitrag woanders hin gehört) und nicht nur das: Nahezu ebenso neu bin ich auch in der C++ Programmierung. Im angehängten Quellcode Auszug seht Ihr meine ersten Versuche. Es geht im Auszug im Wesentlichen darum, dass ich gewisse vorgeschriebene Werte einhalte. Ich gebe bestimmte dynamische Variablen ein und starte aufgrund dieser Werte diverse Berechnungen! Die Ergebnisse der Berechnungen sollen dann mit den vordefinierten Werten verglichen werden! Sollte z.b. die Steigung / Gefälle den Wert 2.25 % überschreiten, wird die Abfrage erneut gestartet! Das klappt auch. Nun habe ich mir aber, verspielt wie ich nun mal bin, gedacht, dass ich mir die Option, in ein anderes Programm zu wechseln, und erst später die Werte erneut einzugeben, offen halten möchte. Aus "Sicherheitsgründen" soll mich aber das Programm nach einiger Zeit "rauswerfen" und mich zum erneuten Login auffordern. Danach soll es einfach wieder wie vorher beschrieben weiter gehen bis die vorgeschriebenen Werte eingehalten werden. Soweit so gut, wenn ich die für "pause" auch den Wert Pause eingebe und nicht pause0 wie für die Warteschleife gefordert, klappt die erneute Abfrage auch. Wenn ich aber die Warteschleife ausführen lasse, indem ich die while - Bedingung erfülle, springt er zwar korrekt zur erneuten Abfrage der anfangs gefragten Werte, jedoch werden alle cin und getchar(); ignoriert, als wären sie gar nicht da! Bitte daher um Hilfe, wo der Fehler liegt, ich komm einfach nicht drauf! Danke vorab und LG Martin

    cout << "Bitte geben Sie zunaechst die jeweiligen Hoehen der Zwischenpunkte ein!" << endl;
    	cout << "Hoehe Zwischenpunkt 1 :";
    	cin >> dHoeheZP1;
    	getchar();
    	cout << "Hoehe Zwischenpunkt 2 :";
    	cin >> dHoeheZP2;
    	getchar();
    
    	cout << "Danke! Die erste Berechnung wird nun gestartet..." << endl;
    	getchar();
    
    	dHoehenunterschiedZP = dHoeheZP2 - dHoeheZP1;
    
    	cout << "Der zu überwindende Hoehenunterschied auf diesem Streckenabschnitt beträgt " << dHoehenunterschiedZP << "m" << endl;
    	getchar();
    
    	dHoehenparameter = (100*dHoehenunterschiedZP)/sqrt((iLaengeZP1ZP2*iLaengeZP1ZP2)-(dHoehenunterschiedZP*dHoehenunterschiedZP));
    
    	string pause;
    	string right_pause = "pause";
    
    	while(dHoehenparameter > dHoehenparameterV)
    	{
    		cout << "Der Hoehenparamter " << dHoehenparameter << " % ist unzulässig! Bitte ueberpruefen Sie Ihre Eingaben oder passen Sie das Gelaende am Zwischenpunkt 2 an!";
    		cout << "Um Ihre Eingaben zu wiederholen, druecken Sie 'Enter'!" << endl;
    		cout << "Um Ihre Strecke zu bearbeiten, geben Sie bitte 'pause0' ein!" << endl;
    		cin >> pause;
    
    		if(pause != right_pause)
    		{
    			Sleep (3000);
    
    			long int wartezeit = 600000;
    			long int milliseconds = 1;
    
    			for(milliseconds=1; milliseconds < wartezeit; milliseconds++)
    			{
    				cout << "Ok...";
    				Sleep(420000); // soll geändert werden auf 600000 (=10 Min)
    
    				if(milliseconds=wartezeit)
    				{
    				cout << "Wartezeit erreicht!" << endl;
    				cout << "Bitte loggen Sie sich erneut ein!";
    				cin >> Benutzer;
    				getchar();
    				cout << "Bitte geben Sie Ihr Passwort ein!";
    				cin >> password;
    				// Passwortabfrage siehe entsprechende Funktion!
    
    				getchar();
    				}
    
    			}
    		}
    
    		getchar();
    
    		cout << "Bitte geben Sie zunaechst die jeweiligen Hoehen der Zwischenpunkte ein!" << endl;
    		getchar();
    		cout << "Hoehe Zwischenpunkt 1 :";
    		cin >> dHoeheZP1;
    		getchar();
    		cout << "Hoehe Zwischenpunkt 2 :";
    		cin >> dHoeheZP2;
    		getchar();
    
    		cout << "Danke! Die erste Berechnung wird nun gestartet..." << endl;
    		getchar();
    
    		dHoehenunterschiedZP = dHoeheZP2 - dHoeheZP1;
    
    		cout << "Der zu überwindende Hoehenunterschied auf diesem Streckenabschnitt beträgt " << dHoehenunterschiedZP << endl;
    		getchar();
    
    		dHoehenparameter = (100*dHoehenunterschiedZP)/sqrt((iLaengeZP1ZP2*iLaengeZP1ZP2)-(dHoehenunterschiedZP*dHoehenunterschiedZP));
    	}
    
    	if (dHoehenparameter <= dHoehenparameterV)
    	{
    		cout << "Der Hoehenparameter " << dHoehenparameter << " % entspricht den definierten Regeln! Sie koennen Ihre Planung nun fortsetzen!" << endl;
    		getchar();
             {
    



  • Mod

    Kannst du bitte ein vollständiges Minimalbeispiel bringen, mit genauer Beschreibung, was du eingibst, was passiert, und was du stattdessen erwartet hättest? Momentan ist es sehr schwer, deiner Problembeschreibung zu folgen.
    Siehe: Wie man Probleme nachstellbar und nachvollziehbar macht

    Allgemein fällt beim ersten Blick auf:
    -Sehr viele getchars ohne ersichtlichen Sinn.
    -Gemischte Benutzung der C-Eingabefunktionen (z.B. erwähntes getchar) und der C++-Eingabefunktionen (alles mit cin), was schief gehen kann.



  • Hallo, vielen Dank für die schnelle Antwort. Ich habe mir dein Feedback wegen der Vermischung von getchar mit cin zu Herzen genommen. Ich habe überall, wo eine doppelte Eingabeaufforderung, zu finden war, dieselbe rausgelöscht. Also cout << "Text"; cin >> Variable; [Weitere Programmausführung] sowie statt getchar() getch() verwendet und das auch nur dort wo es wirklich nötig war. Bei der Wiederholung der Schleifen wird nun wieder jeder einzelne einzugebende Wert abgefragt.

    Trotzdem ergibt sich immer noch ein Problem!

    Im Anhang ist diesmal der Beginn meines Programms als ausführbares Minimalbeispiel zu finden, wo das Problem auftritt. Im Kommentar zu Beginn der Schleife zur Passwortprüfung ist das Problem genau beschrieben.
    Danke vorab und freundliche Grüße,
    Martin

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <Windows.h>
    #include <conio.h>
    
    using namespace std;
    
    string password(char replace = '*')
    
    {
    
    	string password;
    	string right_password = "Goldschatz";
    	char now = '\0';
    
    	cout << "Bitte geben Sie nun Ihr Passwort ein: ";
    
    	// (cin fällt weg, da sonst die Schleife erst nach Eingabe ausgeführt wird, Schleife ist so geschrieben, dass Passworteingabe nötig ist siehe Bedingung!)
    
    // Schleife für Eingabe des Passwortes in *Zeichen
    	while(now != '\r')
        {
            now = getch();
    
            // Sonderzeichen ignorieren
            // Bestehen aus 2 Zeichen - also nochmals getch() aufrufen
            // Siehe FAQ-Beitrag "Einlesen von Pfeiltasten, F-Tasten und Tastenkombinationen"
            if(now == 0 || now == 0xE0)
            {
                getch();
                continue;
            }
    
            // Steuerzeichen ignorieren (Haben ASCII-Codes kleiner als 32)
            if(now < 32)
                continue;
    
            // Zeichen anhängen und Ersatzzeichen ausgeben
            password += now;
            std::cout << replace;
        }
    
    	while(password != right_password)
    
    	{
    		cout << "Passwort falsch! Bitte geben Sie Ihr Passwort erneut ein: ";
    		cin >> password; /*wenn ich diesen Teil weglasse, ist zwar die Ausführung der Eingabeschleife für * - Ausgabe theoretisch möglich, 
    							da es sich ja um den nächsten Befehl (wie zuvor, wo die Eingabeschleife das tut, was sie soll!), handelt, aber soweit kommt es gar nicht!
    							Es kommt zu einer Endlosschleife bis zur 
    							nächsten alleinigen Eingabeaufforderung zwecks Unterbrechung der Schleife!  */
    		while(now != '\r')
    		{
            now = getch();
    
            // Sonderzeichen ignorieren
            // Bestehen aus 2 Zeichen - also nochmals getch() aufrufen
            // Siehe FAQ-Beitrag "Einlesen von Pfeiltasten, F-Tasten und Tastenkombinationen"
            if(now == 0 || now == 0xE0)
            {
                getch();
                continue;
            }
    
            // Steuerzeichen ignorieren (Haben ASCII-Codes kleiner als 32)
            if(now < 32)
                continue;
    
            // Zeichen anhängen und Ersatzzeichen ausgeben
            password += now;
            std::cout << replace;
    		}
    
    	}
    
    	return password;
    
    }
    
    int main()
    
    {
    	password();
    
    	cout << "Hallo! Bitte helfen!";
    	getch();
    
    	return 0;
    }
    


  • venezianer27 schrieb:

    sowie statt getchar() getch() verwendet

    Das macht es nicht besser sondern schlechter. Statt C und C++ zu mischen, mischt Du jetzt low-level Betriebssystemfunktionen und C++.

    und das auch nur dort wo es wirklich nötig war.

    Also... nirgendwo?



  • Ich verstehe das Problem noch immer nicht. Warum diesen ganzen komplizierten Code? Warum nicht so?

    void password()
    {
      string password;
      string right_password = "Goldschatz";
    
      cout << "Bitte geben Sie nun Ihr Passwort ein: ";
      getline(cin, password);  // Besser getline statt "cin >> password" nutzen damit auch Leerzeichen eingelesen werden
    
      while(password != right_password)
      {
        cout << "Passwort falsch! Bitte geben Sie Ihr Passwort erneut ein: ";
        getline(cin, password);
      }
    }
    

    Oder muss das Passwort unbedingt mit den Sternchen angezeigt werden? Wieso bist du überhaupt der Meinung dein Programm mit einem Passwort schützen zu müssen? Wenn niemand dein Programm bedienen soll während du weg bist nutze doch einfach die "Bildschirm sperren" Funktion deines Betriebsystems.



  • Hallo danke für die Antwort und die prompten Tipps und die Hilfe dadurch! 🙂

    Wie gesagt ich bin noch ziemlicher Neuling und da probiere ich einfach gern herum und greife aufgrund meiner Neugier auch manchmal einfach ein bisschen (zu weit) vor! Drum auch die Sache mit dem Passwort! Natürlich ist es in diesem Fall ziemlich unnötig und noch unnötiger die Sache mit den Sternchen!
    Bezüglich getch();: Ein klares Produkt meiner Unwissenheit: Meine Intention war einfach, nach manchen Ausgaben quasi einen einfachen Wartepunkt zu setzen, um nicht alles auf einmal durchlaufen zu lassen und den User zur Bestätigung (seiner Eingaben) aufzufordern, und quasi zu fragen ob er weitermachen will. Und da ich wie gesagt ziemlicher Neuling bin, wusste ich nicht, dass es ohne getch bzw. getchar in solchen Fällen ja auch geht und die wichtigen Ausgaben sowieso durch das Warten auf die Eingabe eines für die Rechnung notwendigen Parameters unterbrochen werden bzw man die Ausgaben entsprechend gestalten kann.

    Wie erwähnt danke für die Tipps! 🙂 Damit wäre die Sache wohl vorerst erledigt, denn warum mit Gewalt kompliziert wenns in diesem Fall auch einfach geht und es grad weil ich in den Kinderschuhen stecke auch vermutlich besser wäre etwas kleiner anzufangen.

    Aber zwei Fragen hab ich dennoch weils mich nicht in Ruhe lässt: Wie würde die mehrmalige Passwortabfrage (jedesmal mit Sternen) bzw evtl. auch ein Rauswurf nach zu vielen fehlgeschlagenenen Loginversuchen bei einem großen Programm aussehen? Läge ich speziell bezüglich der vergeblichen Loginversuche mit einer for Schleife in Kombi mit if richtig?

    LG



  • Ja, vermutlich wäre das dann am user persistent hinterlegt und würde bei jedem Login-Versuch anhand der gewünschten Regeln verwaltet werden (Anzahl Fehlversuche über x-Zeitraum, letzter Fehlversuch, Login-Sperre(bool))



  • Gibt es eine Möglichkeit einfach gewisse Schritte zu überspringen? Zb wenn ich gewisse Programmteile grad nicht brauche? Oder ist das auf Konsolenbasis ein völliger Unfug?



  • Nun ja, es gibt die Möglichkeit per if und else den programmmfluss zu steuern.

    In klassischer Software gibt wohl
    Meist der Nutzer dieser Software durch Interaktion mit dieser vor, welche Teile des Programmes gerade Arbeit zu leisten haben.



  • Ok super danke! Sowas hatte ich mir eh auch überlegt nur ich dachte vl gibt's da auch irgendeine spezielle Funktion mit der es mit einem bis zwei Funktionen wie zb jump oder so auch geht! Aber in diesem Fall wäre vermutlich if und else wirklich das einfachste. Lg



  • Belassen wir es einfach mal dabei, dass es das nicht gibt 😉


Anmelden zum Antworten