Struct Array In Funktion Werte zuweisen
-
Halli Hallo,
als meinen ersten Post in diesem so gut besuchtem Forum, möcht ich sogleich ein kleines Anfängerproblemchen euch mitteilen, welches mich seit gestern nervt:
Ich muss über eine Funktion eingabe/ausgabe eines Struct-Arrays regeln.
Bis jetzt habe ich es nur geschafft, eine Ausgabe (mit im Haupprogramm eingegebenen Werten) zu erzeugen. Nun möchte ich zudem eine Eingabe in einer Funktion verschachteln.Hier der Code wie ich es bis jetzt gemacht habe:
#include <stdlib.h> //Struct erstellen struct test { char dat1[20]; int dat2; }; //Prototyp void unter (test *,int); //Hauptprogramm void main () { int i,f; cout<<"Wieviele PC's moechten Sie erfassen ? : "; cin>>f; test pcs[f]; cout<<"\n"<<endl; for (i=0;i<f;i=i+1) //Dies soll als Funktion gesteuert werden { cout<<"Bitte geben Sie die HDD Groesse fuer den "<<i+1<<".ten PC an : "; cin>>pcs[i].dat1; } cout<<"\nIm Hauptprogramm : "<<endl; for (i=0;i<f;i=i+1) { cout<<pcs[i].dat1<<endl; } //Übergabe an das Unterprogramm unter (pcs,f); system ("pause"); } //Funktion (Unterprog) void unter ( test *pcu,int anz) { int i; cout<<"\n"<<endl; cout<<"Im Unterprogramm : "<<endl; for (i=0;i<anz;i=i+1) { cout<<pcu[i].dat1<<endl; } //pcu[1].dat1="b"; }
Ich habe schon alles mögliche versucht, nur leider komm ich nicht drauf. Ich denke mal es hat etwas mit Zeigern zu tun?
Würd mich freuen wenn ihr mir weiterhelfen könntet.
Mit Grüßen
Flamboy
-
test pcs[f];
f ist nicht zu kompilezeit bekannt, also musst du es dynamisch anlegen
test * pcs = new test[f]; // am Ende dann delete[] pcs;
Variablen aussagekräftige Namen zu geben hat noch nie geschadet.
Fehlermeldungen mit posten.
-
Flamboyant schrieb:
cout<<"\n"<<endl;
Ist dir bewust das das immer 2 Zeilenvorschübe gibt?
endl ist so viel wie ein '\n' und ein flush.
Ich würde dir '\n' empfehlen, da du flush bestimmt nicht überall benötigst wo du endl verwendest.
-
Hallo,
du solltest dir angewoehnen statt <stdlib.h> <cstdlib> zu schreiben, da man es
in Standard-C++ so schreibt. Aeltere C-Header werden mit einem vorangestellten
'c' (wie o. zu sehen) geschrieben. Dann liegen die Funktionen und Klassen im
Namensraum 'std'. Wir machen den Namensraum daher in der Implementationsdatei
bekannt mittels 'using namespace std;' oder wir schreiben den Namensraum vor die
Funktion (z. B. std::pow()).Erstmal zu deinem Problem:
Du kannst die Ganze Geschichte genauso loesen, wie du es mit der Funktion 'unter'
gemacht hast. Du machst dir eine Funktion 'eingabe' (oder wie du sie eben nennen
willst) und baust dort deinen Code ein:void eingabe(test *Test, int Anzahl) { for (i=0;i<Anzahl;++i) //++i entspricht i = i + 1, ist nur kuerzer :) { cout<<"Bitte geben Sie die HDD Groesse fuer den "<<i+1<<".ten PC an : "; cin>>pcs[i].dat1; } }
Noch ein paar Kleinigkeiten:
Statt
void main ()
schreibt man
int main()
Da main() ein Ergebnis an das OS zurueckliefert, ob das Programm ordnungsgemaess
beendet worden ist oder nicht.int i,f; cout<<"Wieviele PC's moechten Sie erfassen ? : "; cin>>f; test pcs[f];
Diese Vorgehensweise entspricht nicht dem Standard-C++, denn hier muss in '[]'
ein konstanter Wert stehen, was hier nicht der Fall ist.In einem solchen Fall erstellt man das Array dynamisch, was man auf folgende
Art und Weise machen kann:test *pcs = new test[f];
Hier haben wir nun Speicher fuer 'f' Variablen vom Typ 'test' reserviert.
Natuerlich muss dieser Speicher wieder freigegeben werden und man muss so
bald es von noeten ist genau dies tun. Hier koennten wir das vor dem Ende
der main()-Funktion machen:delete[] pcs; //hier delete[], da es sich um ein array handelt
Statt eines Arrays koenntest du auch std::vector nutzen. Dein Programm wuerde
dann folgendermassen aussehen:#include <iostream> //std::cout #include <cstdlib> #include <vector> //std::vector using namespace std; //namensraum std bekannt machen //Struct erstellen struct test { char dat1[20]; int dat2; }; //Prototyp //1. Parameter: Referenz auf einen vector mit 'test'-variablen //Der 2. Parameter kann wegfallen, warum, sehen wir unten void unter(vector<test>&); void eingabe(vector<test>&); //Hauptprogramm int main () { int f; cout<<"Wieviele PC's moechten Sie erfassen ? : "; cin>>f; //wir legen einen vector an, welcher 'f' 'test'-objekte enthaelt. //'f' wird hier als parameter an den konstruktor des vectors uebergeben. vector<test> pcs(f); cout<<"\n"<<endl; eingabe(pcs); cout<<"\nIm Hauptprogramm : "<<endl; //beschreibung iterator: siehe funktion unter() vector<test>::const_iterator It = pcs.begin(); for ( ; It != pcs.end(); ++It) cout<<(*It).dat1<<endl; //Übergabe an das Unterprogramm unter (pcs); system ("pause"); return 0; //main erfolgreich beendet } //end main //Funktion (Unterprog) void unter (vector<test> &TestVec) { /* mit einem iterator ist es moeglich, sich durch die einzelnen elemente eines vectors zu 'haengeln', sie also durchzugehen. TestVec.begin() zeigt auf das erste 'test'-objekt im vector. das ist auch der grund, warum hier der 2. parameter entfaellt, da wir ihn nicht benoetigen. der iterator ist hier const, da wir die objektmember nicht manipulieren wollen (wir greifen nur lesend auf diese zu). */ vector<test>::const_iterator It = TestVec.begin(); cout<<endl; cout<<"Im Unterprogramm : "<<endl; /* TestVec.end() zeigt hinter das letzte element im vector. da wir von allen elementen den member 'dat1' ausgeben wollen, muessen wir solange das naechste element ausgeben (It: ist das aktuelle 'test'-objekt und mit ++It gehen wir zum naechsten 'test'-objekt im vector) bis It hinter das letzte element im vector zeigt (sprich: It == TestVec.end()). */ for ( ; It != TestVec.end(); ++It) cout<<(*It).dat1<<endl; } void eingabe(vector<test>& TestVec) { /* gleiche spiel, wie in der funktion 'unter' mit dem unterschied, dass wir hier die 'test'-objekte manipulieren und wir daher keinen konstanten iterator nehmen duerfen, da wir sonst das objekt nicht veraendern duerfen */ vector<test>::iterator It = TestVec.begin(); for ( int i = 1; It != TestVec.end(); ++It, ++i) { cout<<"Bitte geben Sie die HDD Groesse fuer den "<<i<<".ten PC an : "; cin>>(*It).dat1; } }
Wie o. zu sehen, brauchst du dich beim Einsatz von 'vector' nicht um den
Speichermanagment zu kuemmern, da das die Klasse vector fuer dich uebernimmt.Noch was zu vector: Wenn du einen vector von 'int'-Elementen haben willst,
dann schreibst du 'std::vector<int> x'. Das gleiche gilt natuerlich auch
fuer 'float' oder 'double' oder einen beliebigen anderen Typ.So, hoffe ich hab dich nicht mit Informationen ueberrannt, wollte nur zeigen
dass es auch andere Mittel und Wege gibt, wie man dein Programm ohne new/delete
schreiben kann. Wenn du Fragen hast, hier ist dein Forum :).Falls ich irgendwo einen Fehler gemacht hab, einfach korrigieren ;).
mfg
v R
-
Vielen Dank für die zahlreichen Tipps und Ratschläge.
Werde sie gleich umsetzen und in meinen "Style" mit einfließen lassenAuch ein riesen Dank an "virtuell Realisticer" für die ausführliche Erklärung.
Meinst du es wär möglich mir den code für ein Array anstatt Vector. Da ich Vorlesungsgebunden bin, darf ich net so aus der Reihe tanzen und gleich so professionel Lösungen einfließen lassen :p
Vielen Dank
Flamboy
-
Mit nem Array ist das auch kein Problem. Du nimmst einfach die erste eingabe-
Funktion von meinem Post und ersetzt die entsprechenden Zeilen in deinem Code
durch diese Funktion.Du hast zwar keine Iteratoren mehr, aber du hast immer noch die Arraygrenze
von 0 bis f (in deinem Fall). Naja, hier der Code mit Hilfe eines Arrays:#include <iostream> //std::cout #include <cstdlib> using namespace std; //namensraum std bekannt machen //Struct erstellen struct test { char dat1[20]; int dat2; }; //Prototyp //1. Parameter: Referenz auf einen vector mit 'test'-variablen //Der 2. Parameter kann wegfallen, warum, sehen wir unten void unter(test *, int); void eingabe(test *, int); //Hauptprogramm int main () { int f; cout<<"Wieviele PC's moechten Sie erfassen ? : "; cin>>f; //array dynamisch erzeugen test *pcs = new test[f]; cout<<"\n"<<endl; eingabe(pcs, f); cout<<"\nIm Hauptprogramm : "<<endl; for (int i = 0; i < f; ++i) cout<<pcs[i].dat1<<endl; //Übergabe an das Unterprogramm unter (pcs, f); /* reservierten speicher wieder freigeben. weiterarbeiten mit array hiernach natuerlich nicht mehr moeglich (neu reservierung natuerlich schon): pcs[0].dat1 wuerde zu einem speicherzugriffsfehler fuehren */ delete[] pcs; system ("pause"); return 0; //main erfolgreich beendet } //end main //Funktion (Unterprog) void unter (test *TestArray, int Anzahl) { cout<<endl; cout<<"Im Unterprogramm : "<<endl; for (int i = 0; i < Anzahl; ++i) cout<<TestArray[i].dat1<<endl; } void eingabe(test *TestArray, int Anzahl) { for ( int i = 0; i < Anzahl; ++i) { cout<<"Bitte geben Sie die HDD Groesse fuer den "<<i+1<<".ten PC an : "; cin>>TestArray[i].dat1; } }
So, hoffe ich hab nichts vergessen, aber falls noch en kleiner Fehler irgendwo
drin sein sollte, sollte es kein Problem darstellen diesen zu beheben.mfg
v R
-
Vielen vielen Dank für die Hilfe, endlich funktionierts !
Mein Fehler war glaubich, das ich direkt Elemente des Arrays im Unterprogramm mitpcu[1].dat1="b";
bezeichnen wollte.
Nun klappt es wunderbar.
Vielen Dank nochmal, hab einiges dazu gelernt !