Über Parameter Werte in ein Vector speichern und auslesen
-
Hallo,
ich habe folgendes Problem.
1. Bin ich kein guter Programmiererund bin bisschen am rumbasteln
2. Ich übergebe einer Methode (in diesem Fall einem Konstruktor) mehrere Wert. Nun möchte ich, dass alle Werte in einem Vector gespeichert werden sollen. Ziel ist es, wenn ich zwei Tasten betätige (eine für Vorwärts und eine für Rückwärts), möchte ich den Inhalt des Vectors auf dem Bildschirm ausgeben.Unten könnt ihr mein Quellcode sehen, was ich mir auf die schnelle gebastelt habe.
Mit der for-Schleife übergebe ich dem Konstruktor die Zahlen von 1-4. Diese werden jedoch einzeln dem Vector übergeben. Wie kann ich dafür sorgen, dass alle 4 Zahlen in dem Vector gespeicher werden, bevor ich etwas anderes machen kann?
Wenn ich "v" drücke, dann soll: 0, 1, 2, 3 ausgegebn werden.
Wenn ich "r" drücke, dann soll: 3, 2, 1, 0 ausgegeben werden.
Wenn ich bei der Zahl 2 bin und "v" drücke, dann soll 3 ausgegeben werden, wenn ich jedoch "r" drücke, dann soll 1 ausgegeben werden. Wie kann ich das am besten realisieren?Frage zu Zeile 16. Ist das so richtig, dass ich mit dem Iterator am ende des Vectors anfange und dennoch ein itAlter++ mache? Solle ich hier dekrementieren oder inkrementieren?
Hier ist die Header-Datei.
#include<vector> #include<iostream> using namespace std; class Person { public: Person(int age); ~Person(); std::vector<int> vecAlter; std::vector<int>::iterator itAlter; private: int alter; int zahl; };
Hier ist die CPP-Datei.
#include"Person.h" Person::Person(int age) { vecAlter.push_back(age); cin >> taste; if(taste == "v") { for(itAlter = vecAlter.begin(); itAlter != vecAlter.end(); itAlter++) cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } if(taste == "r") { for(itAlter = vecAlter.end(); itAlter != vecAlter.begin(); itAlter++) cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } Person::~Person() { } int main() { for(int i=0; i<4; i++) { Person *person = new Person(i); } }
-
Hallo, habe leider vorhin vergessen mich anzumelden bevor ich mein Problem abgeschickt habe. Daher kann ich keine Änderungen vornehmen.
In der Header-Datei ist natürlich bei mir die Variable "taste" als char definiert. Die Variable "zahl" taucht nicht mehr auf.
-
DerNoob schrieb:
Frage zu Zeile 16. Ist das so richtig, dass ich mit dem Iterator am ende des Vectors anfange und dennoch ein itAlter++ mache? Solle ich hier dekrementieren oder inkrementieren?
Dekrementieren. Einfach der Intuition freien Lauf lassen
-
Dachte ich mir schon
-
noob222 schrieb:
Dachte ich mir schon
Warum hast du es dann nicht gemacht?
Warum testest du dein Programm nicht einfach
-
Ich habe es getestet, jedoch stimmt mein Ansatz nicht, daher stürzt mein Programm ab, sobald ich die beiden tasten betätige. Daher konnte ich nicht herausfinden was richtig oder was falsch ist.
Mit diesem Ansatz komme ich nicht weit, denn so kriege ich nur die einzelnen Werte in den Vector rein und nich alle zusammen. Muss mir mal gedanken machen wie ich das am besten mache.
-
So, ich habe jetzt mal das Programm überarbeitet, und komme dem Ergebnis näher.
Wenn ich den Debugger laufen lasse, so werden einzeln die Werte 5,6,7,8 in den Vector gespeichert.
Wenn ich v das erste mal drücke, dann ist im Vector die Zahl 5.
Wenn ich v das zweite mal drücke, dann ist im Vector die Zahlen 5,6
Wenn ich v das dritte mal drücke, dann ist im Vector die Zahlen 5,6,7
Wenn ich v das vierte mal drücke, dann ist im Vector die Zahlen 5,6,7,8Also bis Zeile 35 ist es soweit gut, aber wie kann ich das ganze auch noch rückwärts realisieren? Ich benötige also bei dem zweiten if eine Idee. Sprich, wenn im Vector die Zahlen 5,6,7 sind und ich r drücke, dann sollen nur noch die Zahlen 5,6 ausgegeben werden.
Hat einer eine Idee?#include"Person.h" Person::Person(int age) { alter = age; zahlAufnehmen(alter); } Person::~Person() { } void Person::zahlEinlesen() { int a = 6; int b = 7; int c = 8; zahlAufnehmen(a); zahlAufnehmen(b); zahlAufnehmen(c); } void Person::zahlAufnehmen(int zahl) { vecAlter.push_back(zahl); cin >> taste; if(taste == "v") { for(itAlter = vecAlter.begin(); itAlter != vecAlter.end(); itAlter++) { cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } if(itAlter == vecAlter.end()) { if(taste == "r") { for(itAlter = vecAlter.end(); itAlter != vecAlter.begin(); --itAlter) cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } } } int main() { Person *person = new Person(5); person->zahlEinlesen(); }
-
Person::Person(int age) { vecAlter.push_back(age); cin >> taste; if(taste == 'v') { for(itAlter = vecAlter.begin(); itAlter != vecAlter.end(); itAlter++) cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } if(taste == 'r') { for(itAlter = vecAlter.end()-1; itAlter != vecAlter.begin()-1; itAlter--) cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } }
So, 2 Fehler gefunden:
1. Du musst 'v' und 'r' in Hochkommas, nicht in Anführungszeichen setzen, sonst vergleichst du char mit char*
2. Das vecAlter.end()-1 und vecAlter.begin()-1, da vecAlter.end() eins nach das letzte Element des Vectors zeigt.
(sonst würde 'itAlter != vecAlter.end()' ja schon abbrechen, bevor das letzte Element ausgegeben wurde)
Entsprechend natürlich das mit dem begin()Ob das deine Designfrage gelöst hat, weiß ich natürlich nicht.
EDIT: Du warst schneller mit Posten.
-
noob222 schrieb:
So, ich habe jetzt mal das Programm überarbeitet, und komme dem Ergebnis näher.
Wenn ich den Debugger laufen lasse, so werden einzeln die Werte 5,6,7,8 in den Vector gespeichert.
Wenn ich v das erste mal drücke, dann ist im Vector die Zahl 5.
Wenn ich v das zweite mal drücke, dann ist im Vector die Zahlen 5,6
Wenn ich v das dritte mal drücke, dann ist im Vector die Zahlen 5,6,7
Wenn ich v das vierte mal drücke, dann ist im Vector die Zahlen 5,6,7,8Also bis Zeile 35 ist es soweit gut, aber wie kann ich das ganze auch noch rückwärts realisieren? Ich benötige also bei dem zweiten if eine Idee. Sprich, wenn im Vector die Zahlen 5,6,7 sind und ich r drücke, dann sollen nur noch die Zahlen 5,6 ausgegeben werden.
Hat einer eine Idee?-> 'r' parallel zu 'v' abfragen, nicht in der anderen if-Bedingung, diese kann nicht wahr werden, weil du keinen neuen Tastendruck abfragst.
Element löschen:
std::Google << "vector reference" << endl;
-
Also, ich habe weiterhin probleme mit der zweiten if-Abfrage.
Habe jetzt das Programm noch mal etwas geändert.Wenn ich das ganze im Debuger laufen lasse, dann kann ich folgendes beobachten:
Nach dem ich drei mal v gedrück habe, sind folgende Werte im Vector: 5,6,7.
Wenn ich jetzt r drücke, dann kann ich im Debug-Modus sehen, dass nach der Zeile 16 im Vector nur noch die gewünchten Werte 5,6 sind. Bis zur Zeile 17 kann ich mit dem Debuger gehen, dann stürt es ab und ich bekomme die Fehlermeldung: vector iterator not dereferencable.Hier im Forum steht teilweise, das mein Iterator auf eine ungültige Stelle zeigt, bzw auf ein Objekt, das nicht mehr existiert bzw. Zerstört wurde. Damit ist wohl das Objekt "7" gemeint, was zuvor gelöscht wurde und nicht mehr daruf zugreifen kann?
Ich habe alle Varianten ausprobiert: ob vecAlter.end()-1 und vecAlter.begin()-1. Es funktioniert einfach nicht. Wo ist mein Denkfehler?
void Person::zahlAufnehmen(int zahl) { cin >> taste; if(taste == "v") { vecAlter.push_back(zahl); for(itAlter = vecAlter.begin(); itAlter != vecAlter.end(); itAlter++) { cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } if(taste == "r") { for(itAlter = vecAlter.end(); itAlter != vecAlter.begin(); --itAlter) { vecAlter.pop_back(); cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } }
EDIT: Ich hatte von Anfang an die Variable taste als string deklariert und nicht als char und war faul es zu ändern
Daher funktioniert das mit dem "v" und "r"
-
Bei deiner zweiten Schleife initialisierst du deinen Iterator mit end(), was ja ein Element hinter dem letzten Element ist. Dann entfernst du mit pop_back ein weiteres Element. Dein Iterator zeigt natürlich ins Leere.
Wenn du nur rückwärts ausgeben willst nimm doch die reverse iteratoren (rbegin und rend).
-
noob222 schrieb:
Also, ich habe weiterhin probleme mit der zweiten if-Abfrage.
Habe jetzt das Programm noch mal etwas geändert.Wenn ich das ganze im Debuger laufen lasse, dann kann ich folgendes beobachten:
Nach dem ich drei mal v gedrück habe, sind folgende Werte im Vector: 5,6,7.
Wenn ich jetzt r drücke, dann kann ich im Debug-Modus sehen, dass nach der Zeile 16 im Vector nur noch die gewünchten Werte 5,6 sind. Bis zur Zeile 17 kann ich mit dem Debuger gehen, dann stürt es ab und ich bekomme die Fehlermeldung: vector iterator not dereferencable.Hier im Forum steht teilweise, das mein Iterator auf eine ungültige Stelle zeigt, bzw auf ein Objekt, das nicht mehr existiert bzw. Zerstört wurde. Damit ist wohl das Objekt "7" gemeint, was zuvor gelöscht wurde und nicht mehr daruf zugreifen kann?
Ich habe alle Varianten ausprobiert: ob vecAlter.end()-1 und vecAlter.begin()-1. Es funktioniert einfach nicht. Wo ist mein Denkfehler?
void Person::zahlAufnehmen(int zahl) { cin >> taste; if(taste == "v") { vecAlter.push_back(zahl); for(itAlter = vecAlter.begin(); itAlter != vecAlter.end(); itAlter++) { cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } if(taste == "r") { for(itAlter = vecAlter.end(); itAlter != vecAlter.begin(); --itAlter) { vecAlter.pop_back(); cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } }
Du musst das pop_back vor die for-Schleife setzen, sonst ist erstens das end() an der falschen Stelle und zweitens werden mehrere Elemente gelöscht
noob222 schrieb:
EDIT: Ich hatte von Anfang an die Variable taste als string deklariert und nicht als char und war faul es zu ändern
Daher funktioniert das mit dem "v" und "r"
Du solltest bei strings aber
if(strcmp(taste,"r")== 0) //statt if(taste == "r")
verwenden, sonst vergleichst du die Adressen und nicht den Inhalt.
-
Also ich wusst nicht das ich für rbegin() und rend() einen neuen Iterator "reverse_iterator" benötige. habe wie ein verrückter versucht das über den normalen Iterator itAlter zu machen, bis ich gemerkt habe, dass das nicht möglich ist
Mit dem reverse_iterator funktioniert es jetzt mehr oder weniger ich mir das vorstelle.Wenn ich bei der zweiten if-Abfrage bin, kann ich nur mit dem Debuger sehen, dass das letzte Element gelöscht wird. Dafür habe ich die Zeile 18 eingefügt. Sonst kann ich die einzelnen Schritte ohne den Debugger nicht nachvollziehen, weil das CMD sich einfach schließt.
Wie kann ich bei Visual Studio einstellen, dass sich das CMD nicht schließt?Ansonsten fällt mir gerade auf, dass nachdem ich die Taste r drücke, ich gar keine möglichkeit mehr habe die Taste v zu drücken. Habe daran gedacht die Zeile 4-20 in eine while-Schleife zu packen. Aber das macht kein Sinn weil ich weder
while(!vecAlter.empty()) noch while(vecAlter.empty())
gebrauchen könnte.
Wir könnte ich das realisieren (bitte kein Code angeben, möcht das alleine hinbekommen)? Für Idee-Ansätze wäre ich dankbar.
PS: Wenn ich
if(strcmp(taste,"v")==0))
benutze, bekomme ich die Fehlermeldung, dass das erste Parameter (also taste) nicht konvetiert werden kann nach char!
Daher habe ich das mal so gelassen, es funktioniert javoid Person::zahlAufnehmen(int zahl) { cin >> taste; if(taste == "v") { vecAlter.push_back(zahl); for(itAlter = vecAlter.begin(); itAlter != vecAlter.end(); itAlter++) { cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } if(taste == "r") { vecAlter.pop_back(); for(revAlter = vecAlter.rbegin(); revAlter != vecAlter.rend(); ++revAlter) { cout << "Die Person ist " << (*revAlter) << " Jahre alt" << std::endl; cout << "TEST"; } } }
-
Beschreib mal bitte noch genauer, wann du eine Taste drücken können willst bei welchem Objekt.
strcmp() nimmt aber 2 char*, siehe hier:
http://www.cplusplus.com/reference/clibrary/cstring/strcmp/
Kannst du mal bitte deinen Code posten, ich kann mir nicht vorstellen, dass das so funktioniert.
Um das Schließen der Konsole zu verhindern: Obwohl dazu nicht geraten wird, kannst du es mal mit cin.get() am Schluss versuchen.
-
Unten sind die Quell-Codes.
Mein Ziel ist es aus einem Vector die Werte vorwärts und rückwärt auszugeben.
Da mein Vector am Anfang leer ist, kann ich den Inhalt des Vector nur befüllen, wenn ich die Tast v drücke, um vorwärts zu gelanten, daher ist auch dasvecAlter.push_back(zahl);
innerhalb der if schleife.
Ich möchte nun mein Vector mit Werten füllen, daher drücke ich z.B. 3 mal die v Taste. Dann sind folgende Werte im Vector: 5,6,7.
Wenn ich nun r drücke, dann soll mein Vector mir die Werte 5,6 ausgeben.
Wenn ich noch mal r drücke, dann soll er mit den Wert 5 ausgeben.Drücke ich jedoch wieder v, dann soll wieder ein Wert hinzugefügt werden.
Solange ich mein Vector mit Werten befüllen kann, soll ich die Möglichkeit haben, mit v die Liste nach vorne und mit r die Liste nach hinten zu durchlaufen.Hier ist die CPP
#include"Person.h" Person::Person(int age) { alter = age; zahlAufnehmen(alter); } Person::~Person() { } void Person::zahlEinlesen() { int a = 6; int b = 7; int c = 8; int d = 9; int e = 10; zahlAufnehmen(a); zahlAufnehmen(b); zahlAufnehmen(c); zahlAufnehmen(d); zahlAufnehmen(e); } void Person::zahlAufnehmen(int zahl) { cin >> taste; if(taste == "v") { vecAlter.push_back(zahl); for(itAlter = vecAlter.begin(); itAlter != vecAlter.end(); itAlter++) { cout << "Die Person ist " << (*itAlter) << " Jahre alt" << std::endl; } } if(taste == "r") { vecAlter.pop_back(); for(revAlter = vecAlter.rbegin(); revAlter != vecAlter.rend(); ++revAlter) { cout << "Die Person ist " << (*revAlter) << " Jahre alt" << std::endl; cin.get(); } } } int main() { Person *person = new Person(5); person->zahlEinlesen(); return 0; }
Hier ist die Header-Datei
#include<vector> #include<string> #include<iostream> using namespace std; class Person { public: Person(int age); ~Person(); void zahlEinlesen(); void zahlAufnehmen(int zahl); std::vector<int> vecAlter; std::vector<int>::iterator itAlter; std::vector<int>::reverse_iterator revAlter; string taste; private: int alter; };
-
Irgendwie bin ich einfach nicht drauf gekommen, dass du std::string verwendest und nicht char* - Sorry, das erklärt natürlich alles.
Du solltest alle Variablen der Klasse private deklarieren, wenn du nicht drauf zugreifen willst.
1. Wann willst du die Eingabesequenz beenden? Wenn eine andere Taste als v und r gedrückt wird? Wenn der vector leer ist?
2. Du sprichst jetzt von den Elementen 5,6 und 7 - du übergibst die 5. Willst du, dass jetzt immer 1 pro Schleifendurchlauf hinzugezählt wird, oder willst du die Variablen a und b verwenden?