Probleme mit Array



  • Hallo liebe Freunde,

    habe hier ein Programm geschrieben das aus einem fuhrpark besteht(kein oop erstmal) welcher eine struktur ist und indem sich eine struktur autos befindet, dieser soll maximal 30 autos aufnehmen, hab jetzt alles soweit richtig nur schreibt mir das programm alles nur in das erste element , ach seht selbst(danke im voraus für jede hilfe)

    #include <iostream>
    #include <conio.h>
    
    using namespace std;
    
    struct skfz
    {
           string marke;
           string farbe;
           double leistung;
           int anzahl_tueren,baujahr,nr;
    };
    
    struct fuhrpark
    {
           skfz autos[29];
           int anzahl;
    
    int eingabe()
    {
         int i=0;
         string antw;
         do
         {              
                   cout<<"#####Eingabe#####"<<endl;
                   cout<<"_________________"<<endl<<endl;
                   cout<<"Marke: "; cin>>autos->marke;cout<<endl;
                   cout<<"Farbe: "; cin>>autos->farbe;cout<<endl;
                   cout<<"Leistung in PS: "; cin>>autos->leistung;cout<<endl;
                   cout<<"Anzahl der Tueren: "; cin>>autos->anzahl_tueren;cout<<endl;
                   cout<<"Baujahr: "; cin>>autos->baujahr;cout<<endl;
                   cout<<"Nummer: "; cin>>autos->nr;cout<<endl<<endl;
                   cout<<"Eingabe beenden?: ";cin>>antw;cout<<endl;
                   i++;
         }
         while(antw!="Ja"&&i<=30);
         return i;
    };
    
    void ausgabe()
    {
         cout<<"#####Ausgabe#####"<<endl;
         cout<<"_________________"<<endl;
         cout<<"Marke: "<<autos->marke<<endl;
         cout<<"Farbe: "<<autos->farbe<<endl;
         cout<<"Leistung in PS: "<<autos->leistung<<endl;
         cout<<"Anzahl der Tueren: "<<autos->anzahl_tueren<<endl;
         cout<<"Baujahr: "<<autos->baujahr<<endl;
         cout<<"Nummer: "<<autos->nr<<endl;
    
    };
    
    };
    int main() 
    {
        fuhrpark fp;
        int anz;int j=0;
        anz=fp.eingabe();
        do
        {
        j++;                       
        fp.ausgabe();
        }
        while(j<=anz-1);                             
    
        getch();
        return 0;
    }
    


  • Ja, klar, du misbrauchst das Array ja auch als Pointer (wusste garnicht dass das mit "a->element_member" auch geht *g*).
    Probier mal so:

    int eingabe()
    {
         int i=0;
         string antw;
         do
         {
                   skfz* a = autos[i];
    
                   cout<<"#####Eingabe#####"<<endl;
                   cout<<"_________________"<<endl<<endl;
                   cout<<"Marke: "; cin>>a->marke;cout<<endl;
                   cout<<"Farbe: "; cin>>a->farbe;cout<<endl;
                   cout<<"Leistung in PS: "; cin>>a->leistung;cout<<endl;
                   cout<<"Anzahl der Tueren: "; cin>>a->anzahl_tueren;cout<<endl;
                   cout<<"Baujahr: "; cin>>a->baujahr;cout<<endl;
                   cout<<"Nummer: "; cin>>a->nr;cout<<endl<<endl;
                   cout<<"Eingabe beenden?: ";cin>>antw;cout<<endl;
                   i++;
         }
         while(antw!="Ja"&&i<=30);
         return i;
    }
    
    void ausgabe(size_t i)
    {
         asssert(i < (sizeof(autos)/sizeof(autos[0])));
    
         skfz* a = autos[i];
    
         cout<<"#####Ausgabe#####"<<endl;
         cout<<"_________________"<<endl;
         cout<<"Marke: "<<a->marke<<endl;
         cout<<"Farbe: "<<a->farbe<<endl;
         cout<<"Leistung in PS: "<<a->leistung<<endl;
         cout<<"Anzahl der Tueren: "<<a->anzahl_tueren<<endl;
         cout<<"Baujahr: "<<a->baujahr<<endl;
         cout<<"Nummer: "<<a->nr<<endl;
    }
    


  • So ganz nach "kein oop erstmal" sieht das doch gar nicht aus. Immerhin hast du deinem Fuhrpark-struct bereits Methoden verpasst.

    Ich habe dann noch drei Anmerkungen zum "Design":

    1. Vom Gesamtkonzept wäre es (nach meiner getrübten Meinung [Ich hatte noch keinen Kaffee]) sinniger, die Ein- und Ausgabe-Methoden für *ein* Fahrzeug/Auto in das struct skfz zu packen.

    2. In deinem Fuhrpark hast du bereits eine Instanzvariable namens "anzahl". Diese schlummert ganz ungenutzt vor sich hin. Mein Vorschlag wäre, diese einfach nach ihrer Bestimmung zu nutzen und die Anzahl der gespeicherten Fahrzeuge darin aufzunehmen. So sparst Du dir auch das fehleranfällige Überführen der Anzahl aus eingabe() nach main() nach ausgabe().

    3. Benutze std::vector 😉

    Man möge mir vergeben, wenn ich total daneben liege.

    Mit nunmehr ersten coffeingetränken Grüßen...

    Heiko



  • Kleine Korrektur:

    hustbaer schrieb:

    ...

    skfz* a = &autos[i];
    

    Alternative 1:

    cout<<"#####Eingabe#####"<<endl;
                   cout<<"_________________"<<endl<<endl;
                   cout<<"Marke: "; cin>>autos[i].marke;cout<<endl;
                   cout<<"Farbe: "; cin>>autos[i].farbe;cout<<endl;
                   cout<<"Leistung in PS: "; cin>>autos[i].leistung;cout<<endl;
                   cout<<"Anzahl der Tueren: "; cin>>autos[i].anzahl_tueren;cout<<endl;
                   cout<<"Baujahr: "; cin>>autos[i].baujahr;cout<<endl;
                   cout<<"Nummer: "; cin>>autos[i].nr;cout<<endl<<endl;
                   cout<<"Eingabe beenden?: ";cin>>antw;cout<<endl;
                   i++;
         }
    

    Alternative 2: ("Eingabe auslagern", "Fuhrpark" als vector implementieren & StandardIO-Idiome verwenden)

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    
    using namespace std;
    
    // Das eigentliche Fachobjekt
    struct KFZ {
           string marke;
           string farbe;
           double leistung;
           int anzahl_tueren,baujahr,nr;
    };
    
    // Ein- Ausgabe-Routinen für KFZ
    istream& operator>>(KFZ& a, istream& in) {
       cout<<"Marke: "; in >> a.marke;
       cout<<"\nFarbe: "; in >> a.farbe;
       cout<<"\nLeistung in PS: "; in >> a.leistung;
       cout<<"\nAnzahl der Tueren: "; in >> a.anzahl_tueren;
       cout<<"\nBaujahr: "; in >> a.baujahr;
       cout<<"\nNummer: "; in >> a.nr;
       cout<<endl;
       return in;
    }
    ostream& operator<<(KFZ const& a, ostream& out) {
       out<<"Marke: "<<a.marke;
       out<<"\nFarbe: "<<a.farbe;
       out<<"\nLeistung in PS: "<<a.leistung;
       out<<"\nAnzahl der Tueren: "<<a.anzahl_tueren;
       out<<"\nBaujahr: "<<a.baujahr;
       out<<"Nummer: "<<a.nr << endl;     
    }
    
    // Ein-/Ausgabe für vector<KFZ>
    istream& operator>>(vector<KFZ>& v, istream& in) {
       string antw = "Nein";
       KFZ tmp;
       while(in && antw != "Ja" && einlesen(tmp, in, out)) {
          v.push_back(tmp);
          cout<<"Eingabe beenden?: ";
          in>>antw;
          cout<<"\n";
       }
       return in;
    }
    ostream& operator<<(vector<KFZ> const& v, ostream& out) {
       out<<"#####Ausgabe#####\n";
       copy(v.begin(), v.end(), ostream_iterator<KFZ>(out, "_________________\n"));
    }
    
    int main() {
        vector<KFZ> fuhrpark;
        cin >> fuhrpark;
        cout << fuhrpark;   
        getch();
        return 0;
    }
    

    "Nicht so schön" ist dabei, dass man mit der Ausgabe bei den operator>>() auf cout festgelegt ist (Anderes gibt die Signatur von operator>>() nicht her). Alternativ kann man eine "einlesen(..., istream&, ostream&);"-Funktion definieren.

    Gruß,

    Simon2.



  • Ich möchte nur kurz anmerken, dass der Thread-Ersteller scheinbar das mit den Array-Grenzen nicht ganz verstanden hat.

    c++-starter schrieb:

    ...
    skfz autos[29];
    ...

    Damit erzeugst Du ein Array mit genau 29 Elementen, d.h. Du kannst hier nur 29 Fahrzeuge speichern. Beim Anlegen eines Arrays gibst Du die Gesamtgröße an:

    skfz autos[30];
    

    Nun der Zugriff: Arrays beginnen beim Index 0 und enden bei n-1 (in diesem Fall bei 29).
    Wenn Du also auf das Array autos zugreifst, dann ist das erste Element bei
    autos[0] und das letzte bei autos[29];

    c++-starter schrieb:

    ...
    while(...i<=30);
    ...

    hier wäre also i < 30 richtig.



  • Also ich danke euch erstmal für alle Tipps, nur verstehe ich im Moment nicht mal das Programmieren von Arrays so ganz, also verstehe ich das mit vectoren erst recht nicht da ich nicht so weit bin, könnt ihr mir eine alternative anbieten ohne vectoren, also wie ich das einfach nur mit arrays lösen kann.



  • c++-starter schrieb:

    Also ich danke euch erstmal für alle Tipps, nur verstehe ich im Moment nicht mal das Programmieren von Arrays so ganz, also verstehe ich das mit vectoren erst recht nicht da ich nicht so weit bin, könnt ihr mir eine alternative anbieten ohne vectoren, also wie ich das einfach nur mit arrays lösen kann.

    Ich weiß jetzt nicht welches deine genauen Probleme sind, versuche aber mal ein wenig Licht in das Dunkel zu bringen.

    Erstmal ein bischen Code...

    int a;
    int a1[5];
    int a2[5] = { 1, 2, 3, 4, 5 };
    int a3[] = { 1, 2, 3, 4, 5 };
    

    ...Jetzt die Erklärung:

    In Zeile 1 wird eine einzelne Variable deklariert die einen Zahlenwert aufnehmen kann. Zeile 2 ist eine Variablendeklaration für ein Array von 5 Einträgen, du kannst dir das als eine Art Schrank mit 5 Fächern vorstellen. Diese Fächer sind durchnummeriert, wobei C++ nicht mit 1 sondern mit 0 beginnt. Somit sind diese Fächer mit 0 bis 4 Nummeriert (Statt mit 1-5 wie es gerne von Neulingen erwartet wird).

    In Zeile 3 zeige ich nur mal kurz wie man einem Array bei der Deklaration gleich Werte zuweisen kann, diese Form geht aber ausschließlich bei der Deklaration. Die zweite Variante in Zeile 4 ist damit identisch, hier wird die Größe durch die Anzahl der dahinter aufgelisteten Felder definiert.

    So erweitern wir das Beispiel noch um ein paar Zuweisungen...

    ...
    a = a2[3];
    a3[2] = a2[4];
    ...
    

    Denken wir uns noch einmal in das Beispiel mit dem Schrank zurück. a2 ist also ein Schrank mit 5 Werten die von 0-4 durchnummeriert sind. In der ersten Zuweisung lesen wir daher nicht etwa das 3te sondern das 4te Element aus, und weisen es der Variablen a zu. Wen du oben schaust ist der 4te Wert mit einer 5 initialisiert gewesen.

    Der zweite Fall sollte damit auch recht einfach sein: der 5te Wert (Index 4) des Arrays a2 wird dem 3ten Wert vom Array a3 zugewiesen.

    ...
    for(int i=0; i<5; ++i)
      a1[i] = 0;
    ...
    

    Hier sieht man eine Möglichkeit wie man nach der Deklaration einem Array Werte zuweist. Unser Array a1 besitzt 5 Einträge, und wie gesagt beginnt die Zählung bei 0. Wir weisen hier jedem Eintrag den Wert 0 zu, man hätte auch alternativ es wie folgt auschreiben können:

    ...
    a1[0] = 0; // Setzt ersten Wert im Array mit 0
    a1[1] = 0; // Setzt zweiten Wert im Array mit 0
    a1[2] = 0; // ...
    a1[3] = 0;
    a1[4] = 0;
    ...
    

    Ich hoffe damit sind alle Klarheiten was Arrays angeht beseitigt.

    cu André



  • Ja das ist mir klar, wie ich das mache ,mein Problem ist also:
    Wie schreibe ich eine Funktion , die als Übergabeparameter ein array auf das auto hat, also damit ich mit dieser funktion in das array auto[29] also 30 autos eingeben kann, ich weiß nicht wie ich die komische parameterübergabe mache, glaube das ist mit zeiger und adress operator oder so



  • c++-starter schrieb:

    Ja das ist mir klar, wie ich das mache ,mein Problem ist also:
    Wie schreibe ich eine Funktion , die als Übergabeparameter ein array auf das auto hat, also damit ich mit dieser funktion in das array auto[29] also 30 autos eingeben kann, ich weiß nicht wie ich die komische parameterübergabe mache, glaube das ist mit zeiger und adress operator oder so

    Drei Möglichkeiten mal aufgeführt:

    #include <iostream>
    
    void fa(int a[5])
    {
    	for(int i=0; i<5; ++i)
    		std::cout << a[i];
    }
    
    void fb(int a[])
    {
    	for(int i=0; i<5; ++i)
    		std::cout << a[i];
    }
    
    void fc(int *a)
    {
    	for(int i=0; i<5; ++i)
    		std::cout << a[i];
    }
    
    int main()
    {
    	int arr[] = { 1, 2, 3, 4, 5 };
    	fa(arr);
    	fb(arr);
    	fc(arr);
    	return 0;
    }
    

    Ich hoffe das reicht. Achtung: Besser noch die Größeninformation als zweiten Parameter mitgeben (z.B. ...void fb(int a[], int count)...) und die fix programmierte 5 aus der Schleife entfernen.

    cu André
    P.S: Vectoren sind von der Bedienung her nicht viel komplizierter (Zumindest wenn man bereits mit dem std-Namensraum gearbeitet hat), erfordern aber keine Pointerarithmetiken und können dynamisch wachsen. Wenn du ein wenig weiter bist solltest du dir das nochmal anschauen oder erklären lassen, da du dir damit einiges ersparst.



  • OK VIELEN DANK, DAS HAT MIR JETZT GEHOLFEN nur eine frage noch, muss ich nicht wenn ich in der funktionsdefinition als parameter einen zeiger angebe, dann in der main funktion als parameter eine adresse also :
    void eingabe(int*)
    {
    ...
    }

    int main()
    {
    int b
    eingabe(&b);
    ...
    }



  • c++-starter schrieb:

    OK VIELEN DANK, DAS HAT MIR JETZT GEHOLFEN nur eine frage noch, muss ich nicht wenn ich in der funktionsdefinition als parameter einen zeiger angebe, dann in der main funktion als parameter eine adresse also :
    void eingabe(int*)
    {
    ...
    }

    int main()
    {
    int b
    eingabe(&b);
    ...
    }

    Jein... Der Hintergrund ist der, das Arrays an sich schon eine Art Zeigerkonstrukt bilden. Arrays sind in sofern mit Samthandschuhen zu behandeln, das sie sich in einigen Punkten etwas anders als erwartet verhalten: Ob nun wie hier wegen der Übergabe da du bei einer Arrayübergabe eigentlich nur einen Zeiger auf das erste Element übergibst - Die weiteren Elemente liegen direkt hintereinander im Speicher), oder das man bei der dynamischen Allozierung von Arrays aufpassen muss die mit delete[] zu löschen.

    Vielleicht kann dir folgendes das ganze verdeutlichen:

    //... Funktionen Wie im vorherigen Beispiel von mir
    int main()
    {
    	int *arr = new int[5];
    	for(int i=0; i<5; ++i)
    		arr[i] = i*2;
    	fa(arr);
    	fb(arr);
    	fc(arr);
    	delete[] arr;
    
    	std::cin >> arr[1];
    	return 0;
    }
    

    Hier lege ich dynamisch ein Array an, wie du aber bereits in Zeile 5 siehst, ist der Zugriff identisch (Da es sich eigentlich in beiden Fällen um ein Pointer handelt).

    cu André



  • c++-starter schrieb:

    ...nur verstehe ich im Moment nicht mal das Programmieren von Arrays so ganz, also verstehe ich das mit vectoren erst recht nicht ...

    Das ist ein Trugschluss ! Im Prinzip kannst Du vector als vereinfachtes Array sehen.
    (Ich weiß, es gibt Leute, die meinen, man soll erstmal "wissen, wie's hinter den Kulissen aussieht", aber der Meinung bin ich nicht - und von denen will seltsamerweise auch niemand auf ASM- oder Chipebene hinunter)
    Gerade z.B. die "Degeneration auf Pointer" ist bei Arrays lästig, bringt einen kein Stück weiter und hat man bei vector eben nicht mehr...

    Sagen wir mal so: Wieso nicht gleich richtig machen ?

    Gruß,

    Simon2.


Anmelden zum Antworten