Anfängerfrage: Konsolen"menü" Ein- und Ausgabe
-
Hallo,
ich bin absoluter Anfänger was programmieren angeht und habe eine Frage bezüglich eines Menüs in der Windows-Konsole.
Und zwar hab ich ein paar Übungen gemacht in denen es z.B. um einfache Ein- und Ausgabe ging.
Also sowas wie:
Farbe
Marke
Gewicht
PSabfragen damit irgendwas machen (PS in KW umrechnen oder so ^^) und direkt wieder anzeigen.
Dabei wird das Programm aber immer nach einmaligem Durchlauf beendet.Daher meine Frage:
Wie kann ich denn quasi ein einfaches Menü bauen, so dass ich z.B. nach dem ersten Durchlauf "Pause" habe und dann [1] für nochmal und [2] für beenden drücken kann?Oder wahrscheinlich etwas komplizierter, dann auch neue Sachen hinzufügen kann, dass dann 2 "Listen" ausgegeben werden usw?
Kann da jemand was zu sagen, oder hat evtl. ein Tutorial parat?
Danke schon mal.
-
AnfängerThomas schrieb:
Wie kann ich denn quasi ein einfaches Menü bauen, so dass ich z.B. nach dem ersten Durchlauf "Pause" habe und dann [1] für nochmal und [2] für beenden drücken kann?
Mit
while,switch,cin,coutWie sieht dein Versuch aus und wo genau ist das Problem?
-
hi, danke erstmal
also ich hab da jetzt ein wenig rumgesucht und probiert mit cin und cout und kann evtl etwas konkreter werden mit meinem Problem

Ich hab jetzt in der Konsole eine Abfrage mit den Punkten 1-4, ok.
Und mit if kann ich da auch sagen was er tun soll.
Z.B:int _tmain() { int eingabe; int anzahl; cout << "Menue:" << endl; cout << "(1) Eingabe neuer Daten" << endl; cout << "(2) Eingabe des Gewichts" << endl; cout << "(3) komplette Ausgabe" << endl; cout << "(4) nur Gewicht und Leistung" << endl; cout << "Eingabe:"; cin >> eingabe; if(eingabe==1){ cout << "\nAnzahl der Fahrzeuge" << endl; cin >> anzahl; int * pFeld = new int [anzahl]; for (int i=0; i<anzahl; i++) { cout << "\nNummer "<< i << " eingeben:"; cin >> pFeld[i]; } }Meine Probleme sind jetzt mehrere:
Erstmal: pFeld, das hab ich so gefunden, wird damit quasi auf ein Element in der Eingabe gezeigt? So eine Vektor dann?
Und abgesehen davon:
Wenn ich da jetzt die 1 drücke und irgendwas eingebe, hab ich ja nur einen Wert eingetragen. Wie kann ich denn mehrere Eigenschaften hinzufügen?Bsp:
Ich trage ein A6
dann das Gewicht
dann die PS-> nächstes Auto
und wenn ich dann die vorher festgelegte Anzahl an Autos eingetragen habe möchte ich das ursprüngliche Menü wieder haben, um z.B. eine Druckoption oder sowas auswählen zu können.
Ich hoffe es ist verständlich worauf ich hinaus will.
-
Nimm eine switch-case Anweisung, ist in deinem Fall besser.
switch(auswahl){ case 1: //... break nicht vergessen!!! case 2: //...hier auch case 3: //...hier auch case 4: //...hier auch default: //...hier auch }Du kannst dir eine struct oder sogar klasse bauen, wenn du das schon kannst. Sonst machst du das mit schleifen.
bool du_noch_autos_hinzufuegen_willst = true; while(du_noch_autos_hinzufuegen_willst){ //einlesen von den Parametern std::cin>>du_noch_autos_hinzufuegen_willst; //noch ein auto?und noch was: new, new[] ist nicht sehr empfehlenswert. schau dir std::vector an.
gruß
syntax
-
Okay, so ganz hab ich das jetzt nicht verstanden.
bool kommt von Boolean? Sprich eine Operation zum Zusammenfügen?Und hab ich das so in etwa richtig gemacht? ^^
Meiner Meinung nach ist Auto jetzt eine Klasse mit 2 Eigenschaften.
Und Auto(); ist eine Funktion(?) zum erzeugen eines Autos und ~Auto(); ist eine Funktion zum entfernen des Autos (letzteres hab ich aber noch nicht verwendet).Ist denn mein Case 1 so in etwa richtig? Ich bekomme da für mich unverständlich Meldungen beim kompilieren:
Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall Auto::~Auto(void)" (??1Auto@@QAE@XZ)" in Funktion "_wmain".
#include "stdafx.h" #include <iostream> using namespace std; class Auto { private: int leistung; int Gewicht; public: Auto(); ~Auto(); void setzenLeistung (int leistung); int lesenLeistung (); void setzenGewicht (int dasGewicht); int lesenGewicht(); }; void Auto::setzenLeistung(int leistung) { this->leistung = leistung; } int Auto::lesenLeistung() { return leistung; } void Auto::setzenGewicht(int dasGewicht) { this-> Gewicht = Gewicht; } int Auto::lesenGewicht() { return Gewicht; } Auto::Auto() { leistung=0; Gewicht=0; } int _tmain() { int eingabe; int anzahl; int KiloWatt; cout << "Menue:" << endl; cout << "(1) Eingabe neuer Daten" << endl; cout << "(2) komplette Ausgabe" << endl; cout << "(3) nur Gewicht und Leistung" << endl; cout << "Eingabe:"; cin >> eingabe; switch(1-4){ case 1: cout << "\nAnzahl der Fahrzeuge" << endl; cin >> anzahl; for (int i=0; i<anzahl; i++) { cout << "\nNummer "<< i << " eingeben:"; Auto KW; cin >> KiloWatt; KW.setzenLeistung(KiloWatt); } } return 0; }
-
ok ein bisschen happerts noch.

Die Klasse sollte so aussehen:
class Auto{ private: int leistung; int gewicht; public: Auto(int l, int g) :leistung(l), gewicht(g){} //diest ist eine Initialisierungsliste ~Auto() //ist bei dir leer, also kannste weg lassen int getleistung() const {return leistung;} //mit const, da nur lesend zugegriffen wird int getgewicht() const {return gewicht;} //gleiche nochmals void setleistung(int l); void setgewicht(int g);Ein boolscher Datentyp kann true oder false sein (0 = false, alles andere true);
Switch-case ist falsch, da kommen keine zahlen rein, sondern die Variable.
gruß
syntax
-
Auto(int l, int g) :leistung(l), gewicht(g){} //diest ist eine Initialisierungsliste ~Auto() //ist bei dir leer, also kannste weg lassen int getleistung() const {return leistung;} //mit const, da nur lesend zugegriffen wird int getgewicht() const {return gewicht;} //gleiche nochmals void setleistung(int l); void setgewicht(int g);Versteh ich jetzt nicht.
Ist das quasi mein ganzer Bereich vor dem main in einem?Also diesen ganzen
int Auto::getleistung()
{
return leistung;
}Kram kann ich mir schenken?
Und das beim switch case war natürlich etwas dämlich
-
Wenn du eine Klasse machst, dann lagerst du die Klasse in 2 Dateien aus, in eine .h und eine.cpp datei.
So:
//Auto.h #ifndef AUTO_H #define AUTO_H class Auto{ };//Auto.cpp #include "auto.h" Auto::set_leistung() //... //...und dann includest du auto.h in der main
#include "auto.h" int main() //...Jain, du kannst dir natürlich nur den Teil schenken, den du natürlich schon definiert hast.
Ich mach so Einzeiler wie
int get_leistung() const {return leistung;}immer in der header-datei.
Den Rest lagere ich in die .cpp Datei aus.
gruß
syntax
-
Hmm,
man muss es aber nicht auslagern, oder?
Denn so umfangreich ist das ja nicht was ich hier mache und ich glaube wenn es noch an einigen Stellen hapert ist es ganz praktisch das beisammen zu haben.Was mich zur nächsten Frage bringt.
Wenn ich da jetzt deine Klasse übernehme, ist doch in der ersten Public-Zeile der Konstruktor oder?
Irgendwie steh ich jetzt total auf dem Schlauch was meine main Funktion betrifft.
Ich muss doch jetzt im ersten Menüpunkt per Konstruktor dem Auto meine Eigenschaften zuweisen.
Er sagt mir aber es ist kein Standardkonstruktor vorhanden.
-
Nein musst du nicht.
Ja, dass ist mein Konstruktor. Ich weiß zwar nicht, was du jetzt genau meinst, aber ich probiere es mal: Ein Konstruktor wird, wenn du ihn nicht explizit definierst, vom Compiler generiert, genau so wie ein Copy-Konstruktor, Destructor, Zuweisungsoperator.
Ein Konstruktor hat den Syntax einer Funktion, ist auch eine, aber eben eine spezielle Funktion, um für ein Objekt Speicher zu reservieren, es zu Initialisieren.Beispiel:
class Auto{ private: std::string name; int ps; int gewicht; int raeder; public: Auto(std::string n, int p, int g, int r) : name(n), ps(p), gewicht(g), raeder(r){} int get_leistung() const { return ps;} int get_gewicht() const { return gewicht;} int get_raeder() const { return raeder;} }; int main(){ Auto Mercedes("mercedes SLK", 470, 2300, 4); //erfundene Werte std::cout<<"PS: "<<Mercedes.get_leistung(); std::cout<<"Gewicht: "<<Mercedes.get_gewicht(); std::cout<<"Raeder: "<<Mercedes.get_raeder(); }Hier wird ein Object namens Mercedes ins Leben gerufen. Mit diesem Objekt kannst du allerlei anstellen, indem du deine Memberfunktionen benutzt.
Du kannst auch mehrere Konstruktoren definieren, wenn du zum Beispiel manche sachen nicht benötigst.
Auto(std::string n, int p, int g, int r); Auto(std::string n, int p, int g); Auto(std::string n, int p); Auto(std::string n); Auto();oder ihnen Default-werte übermitteln:
Auto(std::string n, int p, int g, int r=4);Jetzt klarer? Sonst musst du mal deinen Code posten.
gruß
syntax
-
Erstmal danke für die Hilfe heute, weiter werd ich erst morgen machen

#include "stdafx.h" #include <iostream> using namespace std; class Auto{ private: int leistung; int gewicht; public: Auto(int l, int g) : leistung(l), gewicht(g){} int getleistung() const {return leistung;} int getgewicht() const {return gewicht;} void setleistung(int l); void setgewicht(int g); }; int _tmain() { int eingabe; int PS; cout << "Menue:" << endl; cout << "(1) Eingabe neuer Daten" << endl; cout << "(2) komplette Ausgabe" << endl; cout << "(3) nur Gewicht und Leistung" << endl; cout << "Eingabe:"; cin >> eingabe; switch(eingabe){ case 1: cout << "Fahrzeugeingabe" << endl; Auto A (400, 1000); std::cout<<"ps: " <<A.getleistung(); } return 0; }Das funktioniert so auch.
Aber:
Wenn ich die Werte für Leistung usw. nicht in den Code schreiben will sondern eben per Eintrag in der Konsole (um mir dann eine Liste zu machen mit Name, Farbe oder so, was man dann auch mal als txt speichern kann usw.) muss ich doch statt der Werte dann die Variablen nehmen.
Und dann mit cin und mercedes.setleistung (als bsp.) einfügen.
Da und wenn ich das versuche meckert er. Liegt das schlicht daran, dass am Anfang eben diese Werte als Const angenommen werden?
-
Du musst die Werte nicht direkt in den Konstruktor einschreiben, du kannst das genau so von der Konsole machen, von der Date holen und in eine Datei schreiben...
Beispiel:
std::string name; int ps, gewicht, raeder; std::cin>>name>>ps>>gewicht>>raeder; Auto Neues_Auto(name, ps, gewicht, raeder);gruß
syntax
-
@Syntax_error
Denkst du nicht, dass Klassen für den armen Kerl erstmal zu viel sind? Natürlich ist es so richtig, wie du es vorschlägst, aber wie der OP schon meinte, ist er kompletter Anfänger.
@OP
Mach dich mal mit normalen Ein- und Ausgaben vertraut und schau dir gegebenenfalls Schleifen und switch-Anweisungen an.
Wenn du ein Menü haben willst, welches verschieden oft ausgeführt werden soll, kannst du das über eine while-Schleife regeln (evtl. do-while), die solange ausgeführt wird, bis der Benutzer die Auswahl zum Beenden benutzt. Mit der switch-Anweisung kannst du die Eingabe verarbeiten, um heraus zu finden, ob der Benutzer z.B. den Namen, das Gewicht usw. eingeben will.
Schlüsselwörter sind also:
while und do-while Schleifen, switch-Anweisungen, Variablen, Ein- und Ausgabe und wenn du schon dabei bist, vielleicht auch if-Abfragen.
Also so ziemlich das Standardprogramm was man am Anfang durchkauen sollte.
-
Moin

Also, erstmal habe ich mir jetzt das Buch "C++ Objektorientiertes Programmieren von Anfang an" gekauft

Daher hab ich den Kram nochmal neu geschrieben um mich dabei am Buch zu orientieren. Hoffe da fühlt sich jetzt keiner auf den Schlipps getreten.Mein Ergebnis ist jetzt ein Programm in das ich mehrere Objekte (Autos) einsetzen kann, und auch direkt wieder ausgeben.
Mein nächster Schritt wäre jetzt, nach der Eingabe in Punkt 2 oder 3 springen zu können um den Kram mit bestimmten Eigenschaften, oder später mal sortiert, wieder auszugeben.
Da weiss ich nicht wie ich dann auf meine verschiedenen Eingaben zugreifen soll. Meiner Meinung nach überschreiben sich so ja die neuen Autos immer gegenseitig.
Sprich was muss in case 2 rein?Hier mein Werk

// test2.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <iostream> using namespace std; class Auto { private: char name[20]; int leistung; int gewicht; public: void nameSetzen(); void nameLesen(); void leistungSetzen(); void leistungLesen(); void gewichtSetzen(); void gewichtLesen(); void kilowattLesen(); }; void Auto::nameSetzen() { cin >> name; } void Auto::nameLesen() { cout << "\n" << name; } void Auto::leistungSetzen() { cin >>leistung; } void Auto::leistungLesen() { cout << "\n" << leistung; } void Auto::gewichtSetzen() { cin >>gewicht; } void Auto::gewichtLesen() { cout << "\n" << gewicht; } void Auto::kilowattLesen() { cout << "\n" << leistung/2; } int main() { int eingabe=1; int anzahl; int i; while (eingabe !=4){ cout << "Menue:" << endl; cout << "(1) Eingabe neuer Daten" << endl; cout << "(2) komplette Ausgabe" << endl; cout << "(3) nur Gewicht und PS" << endl; cout << "(4) Exit" << endl; cout << "Eingabe:"; cin >> eingabe; {switch(eingabe){ case 1: cout << "\nAnzahl der neuen Autos eingeben :"; cin >> anzahl; for (i=0;i<anzahl;i++) { Auto Neu; cout << "\nBitte Namen eingeben :"; Neu.nameSetzen(); cout << "\nBitte Leistung eingeben :"; Neu.leistungSetzen(); cout << "\nBitte Gewicht eingeben :"; Neu.gewichtSetzen(); cout << "\nName :"; Neu.nameLesen(); cout << "\nGewicht :"; Neu.gewichtLesen(); cout << "\nPS :"; Neu.leistungLesen(); cout << "\nKilowatt :"; Neu.kilowattLesen(); } break; case 2: } }} return 0; }
-
Du musst deine neu erstellen Autos auch irgendwo abspeichern, damit du später wieder Zugriff auf sie hast. Da empfehle ich dir vector.
Also immer wenn du ein neues Auto erstellst und die Eingaben fertig sind, machst du danachcars.push_back(neues_auto);Später kannst du dann mit einem Iterator, oder einer simplen for-Schleife durch alle Objekte, die in deinem Vector enthalten sind, durch iterieren und die einzelnen Methoden für die Eigenschaften aufrufen.
-
Also das bedeutet dann:
Ich muss noch #include <vector> benutzen,
dann in meiner main einen vector erstellen, den ich z.B. cars nenne, daher -> vector<char> cars; ?Und nach meiner Eingaben müsste ich dann mit cars.push_back(Neu); das grade erstellte hinten in den vector einfügen?
-
Richtig, doch der vector lautet
std::vector<Auto> cars; //nicht std::vector<char> carsgruß
syntax
-
Okay.
Dann speicher ich doch das jeweilige Auto mit allen Eigenschaften an einer Position des vectors.
Macht das nicht Probleme wenn ich dann je nach Menüpunkt nur bestimmte Eigenschaften ausgeben will?
-
Und ein anderes Problem.
Ich dachte mir, zum ausgeben greif ich auf ein bestimmtes Element zu mit Hilfe von vector.at(i).
also:
cout << cars.at(1)
Aber er sagt "Kein "<<" Operator stimmt mit diesen Operanden überein.
Was bedeutet das denn?
-
Das liegt daran, dass du nicht einfach so ein Auto-Objekt ausgeben kannst. Du musst es also ungefähr so schreiben
cars.at(1).leistungLesen();