Problem mit Array



  • Davidlocke13 schrieb:

    #include <vector> habe ich noch nicht gehabt!
    Ich soll für das Programm nur Sachen verwenden die ich schon hatte.

    Es soll eine Funktion für die Eingabe, Ausgabe und später auch noch für die Sortierung der Werte haben.

    Und vom Benutzer soll festgelegt werden wie viel werte er eingibt, deshalb soll ich ein Dynamisches Array verwenden!

    Ist ja alles schön und gut.
    Aber schreib erst einmal ein Programm ohne Funktionen, dann ist schon über die Hälfte der Fehler weg.
    Wenn das Programm läuft, zeigst du uns den Sourcecode und versuchst das mit den Funktionen dann nochmal.



  • #include <iostream>
    using namespace std;
    int main()   
    { 
     int Teilnehmer, i;
     int *Startnummer;
     string *Namen;
     cout << "Wie viele Laeufer haben teilgenommen: ";
     cin  >> Teilnehmer;
     Startnummer = new int [Teilnehmer];
     for (i=0; i < Teilnehmer; i++)
     {
      cout << "Startnummer: ";
      cin  >> Startnummer[i];
      cout << "Name: ";
      cin  >> Namen[i];
     }
     for (i=0; i < Teilnehmer; i++)
     {
      cout << "Startnummer des Teilnehmers : " << Startnummer[i] << endl;
      cout << "Name des Teilnehmers : " << Namen[i] << endl;
     }
      getchar();
      return 0; 
    }
    

    Jetzt stürzt es nach der 1. Eingabe ab !



  • Dein Array für die Namen hast du ja auch noch nicht erzeugt.
    Evtl. solltest du die Arrays für Startnummern und Namen zum Schluß auch wieder löschen.



  • Jo stimmt ! Jetzt habe ich aber echt ein Brett vorm Kopf !



  • hmm nunja da du auf "Namen" mit dem index operator zugreifst, muss man annehmen, dass die teilnehmer alle nur einen namen mit der länge von einem buchstaben haben.

    und wenn du versuchst einen zeiger zu dereferenzieren ohne ihn vorhin auf einen reservierten speicherbereich zeigen zu lassen, hast du zu 99.9999% access violation.



  • weitere kritikpunkte (sorry für doppelpost, wtb edit funktion):

    erstell instanzen immer erst wenn du sie benötigst und dann so lokal wie möglich.

    wenn du mit new arbeitest, musst du den speicher auch wieder freigeben.

    arbeite nicht mit new. manuelle speicherverwaltung ist unnötig aufwendig.

    weisst du überhaupt was std::endl macht oder übernimmst du es einfach stumpf?



  • Davidlocke13 schrieb:

    #include <vector> habe ich noch nicht gehabt!
    Ich soll für das Programm nur Sachen verwenden die ich schon hatte.

    Hattet Ihr schon 'struct'? Falls ja, solltest Du das hier in jedem Fall nutzen.
    Es macht IMHO wenig Sinn new zu lernen und struct nicht zu kennnen.



  • endl sagt doch das selbe wie \n und sorgt für ein Zeilenumbruch.

    struct hatte ich auch noch nicht.



  • Schade, dass du kein gutes C++ machen darfst. Naja, denn musst du es wohl so machen:

    int main()
    {
    	cout << "Wie viele Laeufer haben teilgenommen: ";
    	int Teilnehmer;
    	cin >> Teilnehmer;
    
    	string* Namen     = new string[Teilnehmer];
    	int* Startnummern = new int[Teilnehmer];
    
    	for(int i=0; i<Teilnehmer; ++i)
    	{
    		cout << "Startnummer: ";
    		cin  >> Startnummern[i];
    		cout << "Name: ";
    		cin  >> Namen[i];
    	}
    
    	for(int i=0; i<Teilnehmer; ++i)
    	{
    		cout << "Startnummer des Teilnehmers: " << Startnummern[i] << endl;
    		cout << "Name des Teilnehmers       : " << Namen[i]        << endl;
    	}
    
    	// Aufräumen
    	delete[] Namen;
    	delete[] Startnummern;
    
    	// Warten
    	cin.ignore(100,'\n'); // Sonst wird das mit dem Warten nichts.
    	getchar();
    
    	// Ende - return 0 wird bei der main übrigens automatisch gemacht. Musst du also nicht extra hinschreiben.
    	return 0;
    }
    

    Und nun versuch das Ganze mal in Funktionen auszulagern und den Quellcode zu kommentieren.



  • Davidlocke13 schrieb:

    endl sagt doch das selbe wie \n und sorgt für ein Zeilenumbruch.

    Eben nicht. (Mach dir nichts draus, das denken viele)


  • Mod

    Davidlocke13 schrieb:

    endl sagt doch das selbe wie \n und sorgt für ein Zeilenumbruch.

    Nein. Es ist ein Zeilenumbruch mit anschließendem flush (das heißt die Ausgabe wird mit dem tatsächlichen physischem Ausgabemedium synchronisiert). Das ist sehr oft nicht das, was man möchte, da dies normalerweise eine sehr aufwändige Operation ist. Bei Bildschirmausgaben ist es noch recht egal, da diese in der Regel ohnehin mit jedem Zeilenumbruch synchronisiert werden, aber bei Dateien (und man kann nie wissen, ob cout nicht vielleicht in eine Datei führt) ist das ein riesiger Performancekiller.

    Also endl nur benutzen, wenn man wirklich flushen möchte. Was für Anfänger so gut wie nie sein sollte. Nicht einmal vor Benutzereingaben, wie man denken könnte (damit eine vorherige Frage auch auf dem Bidschirm erscheint): Da cin und cout ge-tie-ed sind, wird cout automatisch geflusht, bevor auf cin eine Eingabeoperation durchgeführt wird.



  • Ok so schaut das bei mir aus !!!

    #include <iostream>
    using namespace std;
    int main()   
    { 
     int Teilnehmer, i;
     int *Startnummer;
     string *Namen;
     cout << "Wie viele Laeufer haben teilgenommen: ";
     cin  >> Teilnehmer;
     Startnummer = new int [Teilnehmer];
     Namen = new string [Teilnehmer];
     for (i=0; i < Teilnehmer; i++)
     {
      cout << "\nStartnummer: ";
      cin  >> Startnummer[i];
      cout << "Name: ";
      cin  >> Namen[i];
     }
     for (i=0; i < Teilnehmer; i++)
     {
      cout << "Startnummer des Teilnehmers : " << Startnummer[i] << endl;
      cout << "Name des Teilnehmers : " << Namen[i] << endl;
     }
     delete[] Namen; 
     delete[] Startnummer; 
     getchar();
     return 0; 
    }
    

    Bin schon wieder dabei die Funktionen einzubauen !

    Übrigens danke für den Tipp mit endl und \n werde ich dann mal entsprechend anwende. Bei mir in der Berufsschule sind die Computer so alt da sollte man den unterschied merken.



  • der code sieht schon besser aus.
    jedoch:

    du hast #include <string> vergessen

    deine variablen sind noch immer nicht so lokal wie möglich

    du hast das mit endl und '\n' noch nicht übernommen


  • Mod

    Davidlocke13 schrieb:

    Übrigens danke für den Tipp mit endl und \n werde ich dann mal entsprechend anwende. Bei mir in der Berufsschule sind die Computer so alt da sollte man den unterschied merken.

    Das hat eigentlich nichts mit der Grundgeschwindigkeit zu tun, sondern vor allem mit der großen Diskrepanz zwischen der Geschwindigkeit des Hauptspeichers und der Massenspeichermedien und auch damit, wie die Massenspeichermedien intern ihre Daten organisieren. Dieser Unterschied war schon immer sehr groß und ist es heute erst recht (SSDs haben die Situation aber etwas verbessert).

    Auf Bildschirmen ist es, wie erwähnt, ohnehin egal, da die Terminalemulatoren bei jedem Zeilenumbruch automatisch von sich aus flushen. Das heißt natürlich im Umkehrschluss auch, dass ein endl dadurch auch auf dem Bildschirm unnötig ist und man einen guten Grund hat, sich Ausgaben ohne endl anzugewöhnen.

    Allgemeiner Tipp: Auf der US-Tastatur tippt sich das '\n' auch fast genau so einfach wie endl. Überhaupt ist sie sehr gut zum Programmieren, da die Erfinder der Sprachen sie in der Regel selber benutzt haben. Dann versteht man auch, wieso scheinbar so umständlich zu tippende Zeichen wie \/[];' bei Computersprachen so oft vorkommen.



  • So und noch ein versuch:

    #include <iostream>
    #include <string>
    using namespace std;
    int main()   
    { 
     int Teilnehmer, i;
     int *Startnummer;
     string *Namen;
     cout << "Wie viele Laeufer haben teilgenommen: ";
     cin  >> Teilnehmer;
     Startnummer = new int [Teilnehmer];
     Namen = new string [Teilnehmer];
     for (i=0; i < Teilnehmer; i++)
     {
      cout << "\nStartnummer: ";
      cin  >> Startnummer[i];
      cout << "Name: ";
      cin  >> Namen[i];
     }
     cout << "Teilnehmerliste:\n\n";
     cout << "Startnummer:\tName:\n";
     for (i=0; i < Teilnehmer; i++)
     {
      cout << Startnummer[i] << "\t\t";
      cout << Namen[i] << "\n";
     }
     delete[] Namen; 
     delete[] Startnummer; 
     getchar();
     return 0; 
    }
    


  • Wenn du jetzt noch Definition und Deklaration von Teilnehmer und Name zusammenfasst und i in der Schleife deklarierts ist es noch etwas besser.
    so etwa:

    int *Startnummer = new int[Teilnehmer];
    
    for (int i=0; i < Teilnehmer; i++)
    


  • Sagt dir eingetlich dein Compiler, dass Definitionen am Anfang der main stehen müssen? Oder wieso machst du das? 😃


  • Mod

    Grauenhaft, aber innerhalb deiner Beschränkungen wohl das Beste was machbar ist.

    Ich würde die Variablen, insbesondere das i, noch lokaler machen. Du kannst for (int i = 0...) schreiben.

    Dir ist schon klar, dass der Streamoperator >> an Leerzeichen trennt? Könnte für die Namen wichtig sein. Aber wie gesagt, innerhalb deiner Beschränkungen wohl das Beste was machbar ist



  • out schrieb:

    Sagt dir eingetlich dein Compiler, dass Definitionen am Anfang der main stehen müssen? Oder wieso machst du das? 😃

    Ich glaube mein Programm verwendet den Borland C++ Compiler.

    Das habe ich so in der Berufsschule gelernt, so mit der Begründung wenn es ganz am Anfang steht kann man es auch nirgends vergessen !



  • Davidlocke13 schrieb:

    Das habe ich so in der Berufsschule gelernt, so mit der Begründung wenn es ganz am Anfang steht kann man es auch nirgends vergessen !

    Dazu fällt mir nichts mehr ein. 😃 😃


Anmelden zum Antworten