?Dynamischer? Array für letter by letter ausgabe *?*



  • Hi leute,

    super forum hier! Hab mich bis jetzt nicht getraut was zu sagen, da ja schon fast alles besprochen wurde. Nun hier ist die lage:
    Ich hab keine Ahnung von C++ (soll sich aber noch ändern) und ich will so eine coole "Trinity an Neo schreibt buchstabe für buchstabe auf screen" ausgabe machen 😃

    Hab schon ein wenig erfahrung mit Delphi, will auch mal OpenGL anfangen (hab mir gedacht, wird schon was drann sein warum alle C++ benutzen 🙂 ).

    Also hier mal mein bisheriger code, dann kommt das problem:

    #include <iostream>
    #include <conio.h>
    #include <string>
    using namespace std;
    
    char * word[5];
    int i, c;
    
    int main()
    {
      c = 0;
      word[0] = "h";
      word[1] = "a";
      word[2] = "l";
      word[3] = "l";
      word[4] = "o";
    
      for(i=1;i<=5;i=i+1)
      {
        Sleep(300);
        cout << word[c];
        c++;
      }
      getch();
      return 0;
    }
    

    Nun, wie man sieht nicht gerade komplex.

    Nun möchte ich aber das man nicht jedes wort in den manuell in den array quetschen muss. Also möchte ich eine funktion machen die mir dann ein array aus soundsovielen chars macht. Hab das auch versucht, aber das klappt nicht. Ich glaub da muss ein dynamischer array her oder wie das teil heißt 🙄

    Kann mir jemand helfen? (Sicher alle, tolles forum 👍 )

    Red

    PS: Whoa, hier hats ja ne menge an Tags 😮



  • Hi!

    Wie ich das verstanden habe willst du das man angeben kann wieviele Zeichen das Array aufnehmen kann ist das richtig?

    Zu deinem Code:
    1. Versuche globale Variablen zu vermeiden. Wie heißt es doch so schön "So lokal wie möglich, so global wie nötig!".
    2. Du musst nicht jeden Buchstaben des Arrays einzeln zuweisen und auch nicht ausgeben, dann muss allerdings dein Array 1 Byte größer sein, damit noch eine Endekennung hinten dranpasst.
    3. Wenn du jeden Buchstaben ausgeben willst, musst du keine 2. Variable anlegen, sondern kann die Variable der Schleife verwenden:

    #include <iostream>
    #include <conio.h>
    // Headerdatei string gelöscht, verwendest du eh nicht, für C-String-Funktionen
    // gibt es die Header cstring
    using namespace std;
    
    int main()
    {
    
      char * word[5];
      word[0] = "h";
      word[1] = "a";
      word[2] = "l";
      word[3] = "l";
      word[4] = "o";
      /* einfacher wäre:
      char* word[6] = "hallo"; */
    
      for(int i=0;i<5;++i) // index beginnt bei 0
      {
        Sleep(300); // auch kein Standard, aber ich lass es mal
        cout << word[i]; // statt c -> i
      }
    
      cin.clear(); // Durch getch ersetzt
      cin.sync(); // getch ist kein Standard
      cin.get(); // Puffer wird geleert, flags gelöscht, warten auf eingabe
    
      return 0;
    }
    

    Wenn du jetzt willst das zuvor jemand angibt wie groß das Wort sein soll, dann geht es so:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      cout << "Wieviel Zeichen? ";
      unsigned long len;
      cin << len;
    
      char* woerter = new char[len+1]; // Speicher reservieren; +1 für Endekennung
      cin.getline(woerter, len); // max. len-Anzahl-Zeichen einlesen
    
      for(size_t i=0; i<len; ++i)
        cout << woerter[i] << endl;
    
      delete [] wort; // nicht vergessen: Speicher freigeben!
    
      return 0;
    }
    

    Leichter wäre es string zu verwenden. Es baut sich dynamisch aus und kann ein paar Mrd.(?) Zeichen aufnehmen:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
      string woerter;
      getline(cin, woerter);
      size_t len = woerter.length();
      for(size_t i=0; i<len; ++i)
        cout << woerter[i] << endl;
      return 0;
    }
    

    Code-Hacker



  • Danke! Ich denke daraus kann ich mir was basteln! Es geht mir darum, das dir buchstaben nacheinander ausgegeben werden. Danke jedenfalls 👍



  • Hi!

    Habe es nochmal editiert, es werden alle Buchstaben nacheinaneder ausgegeben, getrennt durch ein Zeilenumbruch.

    Code-Hacker



  • Ich habs jetzt so versucht, aber es funkt nicht 😡

    #include <iostream>
    #include <string>
    using namespace std;
    
    void schreibe(string text);
    
    int main()
    {
      schreibe("Hallo");
      cin.clear();
      cin.sync();
      cin.get();
      return 0;
    }
    
    void schreibe(string text)
    {
      char* satz = new char[text.length+1];
      satz[text.length] = text;
      for(int i=0;i<text.length;++i)
      {
        Sleep(300);
        cout << satz[i];
      }
    }
    


  • satz[text.length] = text;

    Ich nehme mal an, dass da der Fehler angezeigt wird?
    Du kannst jedenfalls nicht einfach einen string einem array zuweisen - das sind einfach zwei verschiedene Dinge (abgesehen davon, dass man auch nicht einfach arrays einander zuweisen kann).
    Benutz doch einfach konsquent string, tut's doch auch und ist einfacher (zugegebenermaßen evtl. mit geringerem Lerneffekt):

    void schreibe(const string& text)
    {
      for(int i=0;i<text.length();++i)
      {
        Sleep(300);
        cout << text[i];
      }
    }
    


  • Okeeee 😃

    Danke 🙂



  • Hi!

    Ok, das war es ohne Lerneffekt, jetzt mit ;):

    // zu den Includes:
    #include <cstring>
    
    void schreibe(string text)
    {
      size_t len = text.length();
      char* satz = new char[len+1];
      strncpy(satz, text.c_str(), len); // Text nach Satz
      for(size_t i=0;i<len;++i)
      {
        Sleep(300);
        cout << satz[i];
      }
      delete[] satz; // NIEMALS VERGESSEN!!! SPEICHER FREIGEBEN!!!!
    }
    

    Also text nach satz ist eine C-String-Funktion. c_str() macht aus einem String einen Nullterminierten C-String. strncpy kopiert eine bestimmte Anzahl Zeichen. Es gibt auch strcpy, ohne Angabe der Anzahl zeichen, allerdings kann dabei der Puffer überlaufen. Außerdem musst du hinter length Klammern schreiben, du machst dort einen Funktionsaufruf. Ich habe die Variable len aus dem Grund angelegt, damit in der Schleife nicht jedes mal length() aufgerufen werden braucht. Ist eigentlich nur eine Optimierung. Wenn du string benutzt, dann arbeite mit dem Typ size_t für die Längenangabe, immerhin kann ein string wesentlich mehr Zeichen aufnehmen als die größte integer Zahl.

    delete bzw. bei Arrays delete[] darfst du niemals vergessen. Wenn du mal viel Speicher reservieren musst, dann z.B. dynamische Liste, kann es passieren das dein Speicher immer kleiner wird, weil du diesen nicht mehr freigibst. Ich hatte mal einen solchen Fehler in einem großen Projekt, ich musste die gesamte Speicherverwaltung neu schreiben. Windows hatte bereits einmal den virtuellen Speicher vergrößert. Also sehr unschön, wenn man den PC neu starten muss, damit wieder alles vernünftig läuft.

    Code-Hacker



  • mh, gut, aber ich denke ich bleibe bei der einfache variante. 😋

    Jedenfalls gut zu wissen das man einen string wie ein array behandeln kann.

    Red


Anmelden zum Antworten