Pufferung von Texten zur Ausgabe mehrteiliger Inhalte in Konsolenfenstern



  • 1. Davon gibts höchstens ne Netzhautablösung, Krebs am Auge ist sehr unwarscheinlich.

    2. Das einzige, was bei der zuweisung von last nicht passt, ist, dass das ganze auch auserhalb der Schleife passieren könnte.

    3. Nein, ich bin mir sicher, das ich hier doch lieber bei 0 anfange.

    4. Was soll robuster heisen???

    5. Ich würde ja konstruktoren und destruktoren verwenden, nur hat mir noch niemand erklären können, wie die verwendet werden und zu was die gut sind.

    6. Gibt es denn eine alternative zur manuellen zuweisung der Zeiger?

    7. Was soll mir eine assert Anweisung bringen???



  • zu 1.: Ok, da hast du recht. Ist aber auch nicht viel besser.

    zu 2.: Nein! Du weist last ein mit new angelegtes Objekt zu. Später überschreibst du den Zeiger wieder, wodurch der Zugriff auf besagtes Objekt nicht mehr möglich ist. Das nennt man ein Memory-Leak.

    zu 3.: Gut!

    zu 4.: Robust heißt, resistenter gegen Probleme. Das kann zum Beispiel bedeuten, daß auftretende Fehler weniger obskur und damit leichter zu debuggen sind.

    zu 5.: Dann lern es. Das sind elementare Grundlagen und solange du die nicht beherrschst, hat es eigentlich keinen Sinn mit Klassen zu arbeiten. Ich bin mir sicher, daß sich hier im Forum irgendwo ein guter Link dazu findet (mußt halt ein Bißchen suchen).

    zu 6.: Du könntest z.B. die rowbuffer-Objekte "innerhalb" eines linebuffer-Objektes in einen std::vector legen. Dann sparst du dir zumindest schon mal den prev/next-Krempel (sehe sowieso nicht wieso du da an dieser und an anderen Stellen Zeiger brauchst; würde es eine Array-artige Datenstruktur nicht auch tun?)

    zu 7.: Du hast offensichtlich Zeiger-Probleme. assert kann da nützlich sein.



  • re: zu 1. Doch, ist besser, weil vollständig heilbar 😉

    re: zu 2. OK, da hast du recht.

    re: zu 6. Das hab ich schon versucht, das ist Version 4.2 des Textbuffers, version 1.0 - 4.1 haben nicht funktioniert, weil der zugriff nicht möglich war (Frag mal einen gewissen Lars Hupel, was bei vector<vector<char>> passierte, oder bei einem 2dim Array, auserdem ist das ganze stark rudimentär, sollte ursprünglich dynmamisch an die Konsolengröße/Textgröße angepasst werden, hat sich aber erübrigt, ich hab nur keine Lust, das ganze noch mal zu machen, weil es endlich mal funktioniert. Und das gennnte Problem ist auch nicht wirklich teil des Textbuffers). Und zu dem Problem mit den Zeigern bei den Felder, die stellen nur eine vereinfachung dar, z.B. im bezug auf die Ausgabe, bei der ich sonst die Felder aus der liste einzeln auswählen müsste, was mir erstens zu viel Arbeit und zweitens zu unübersichtlich ist.

    re: zu 7. assert hätte die gleiche auswirkung wie der Fehler selbst. (hab mitlerweile nachgeschlagen)

    Und was konstruktoren und destruktoren angeht, so weis ich nur so viel, das der konstruktor ein Objekt anlegt (eine Instanz einer Klasse), und der destruktor dieses Objekt wieder zerstört. Wenn das ganze noch weiterführernde bedeutung hat, bzw. essentiell ist, da wüsste ich das gerne auch mal.



  • Was soll bei std::vector<std::vector<char> > passieren? Das ist ein absolut legales Konstrukt, das bestens funktioniert (jedenfalls, wenn man es korrekt anwendet). Ich nehme an, du beziehst dich jetzt auf irgendeinen anderen Thread. Aber den habe ich offensichtlich nicht mitverfolgt und kann deshalb dazu jetzt nichts weiteres sagen.

    Zu Konstruktor und Destruktor:

    Mit dem Konstruktor wird ein Objekt einer Klasse angelegt und initialisiert. Was du in deiner create_linebuffer-Funktion stehen hast, ist mehr oder weniger das, was stattdessen eigentlich im Konstruktor stehen sollte.

    Der Destruktor zerstört ein Objekt und räumt vorher noch auf. Das fehlt in deinem Code völlig, soweit ich sehe. Du erzeugst Objekte mit new, aber es gibt kein passendes delete dazu.



  • das mit std::vector<std::vector<char>> wurde auch nicht im Forum besprochen, ich kenne Lars persönlich. Und an diesem Konstrukt als solches ist auch nichts auszusetzen, nur das es keine möglichkeit eines organisierten zugriffes gibt, und da könnte ich ja auch gleich ein2dim array nehmen un jeden char einzeln reinschreiben.

    Und zu dem ding mit den Konstruktoren und Destruktoren:

    Wie kann ich aus meinen create-Prozeduren Konstruktoren machen und eine Instanz erzeugen?

    (destruktoren brauch ich nicht, das objekt fieldbuffer soll nicht gelöscht werden, sondern wärend der gesamten Laufzeit aktiv sein)

    (Neue, korrigierte version ist hochgeladen, bitte genauere schilderung der Probleme mit dem Quelltext-Aufbau)



  • Keine Möglichkeit eines organisierten Zugriffs? Und was ist mit:

    Vec[x][y]
    

    ?

    (destruktoren brauch ich nicht, das objekt fieldbuffer soll nicht gelöscht werden, sondern wärend der gesamten Laufzeit aktiv sein)

    Also das will ich mal überhört haben. Es ist zwar in der Regel richtig, daß der reservierte Speicher nach Beendigung des Programms automatisch wieder freigegeben wird. Aber das ist trotzdem keine Entschuldigung für einen fehlenden Desturktor.

    Was den Konstruktor angeht: Ok, ich will mal nicht so sein. Hier ist ein Konstruktor für die Klasse fieldbuffer ausgehenden von dem obigen Quelltext:

    fieldbuffer() : firstline (0), lastline (0), nextwindow (0), lastwindow (0)
          {
               firstline = new linebuffer;
               linebuffer *actualline;
               actualline=firstline;
               pos_x=0;
               pos_y=0;
               for (int i=0; i<25; i++)
               {
                   actualline->nextline = new linebuffer;
                   actualline = actualline->nextline;
                   actualline->create_linebuffer();
                   lastline=actualline;
               };
               firstline->prevline=0;
               lastline->nextline=0;
          };
    


  • Vec[x][y]
    

    Das ist zwar schön und gut, aber ich will, wie gesagt, nicht jeden char einzeln schreiben, und mit schleifen lief es halt nicht, und das ist das, was zählt.

    Und firstline und lastline sind linebuffer, keine fieldbuffer!!!

    Auserdem hab ich Probleme damit, den Konstruktor in das bestehende Progrmm einzubinden (kann sein, das ich einfach nur zu blöd bin, mit Konstruktoren umzugehen.)

    Und was das wichtigste ist, mein problem mit den Zeigern löst das alles ja wohl auch nicht.



  • Und firstline und lastline sind linebuffer, keine fieldbuffer!!!

    Ich habe nirgendwo etwas anderes behauptet.

    Das ist zwar schön und gut, aber ich will, wie gesagt, nicht jeden char einzeln schreiben, und mit schleifen lief es halt nicht, und das ist das, was zählt.

    Sehe das Problem ehrlich gesagt nicht.

    for (std::vector<std::vector<char > >::iterator Iter (Vec.begin()); Iter!=Vec.end(); ++Iter)
        for (std::vector<char>::iterator Iter2 (Iter->begin()); Iter2!=Iter->end(); ++Iter)
        {
            // *Iter2 ist dein char
        }
    

    Edit: Der "Aufruf" des Konstruktors ist in deinem Programm garantiert bereits drinn. Der sieht nämlich entweder so:

    fieldbuffer *FB = new fieldbuffer;
    

    oder

    fieldbuffer FB;
    

    aus.



  • Dann brauche ich also nur den aufruf der create-Methode wegzulassen?

    Und was das problem mit dem organisierten zugriff angeht, das sieht keiner, eigentlich hätte der erst textbuffer schon funktionieren müssen, tat er aber nicht, wie alle anderen, die ich verworfen habe, auch.



  • So ist es.

    Edit:

    Und was das problem mit dem organisierten zugriff angeht, das sieht keiner, eigentlich hätte der erst textbuffer schon funktionieren müssen, tat er aber nicht, wie alle anderen, die ich verworfen habe, auch.

    Und da du die erste (effiziente, wenig fehleranfällige) Implementierung nicht richtig hinbekommen hast, gehst du zu einer anderen über (weitaus weniger effizient und extrem fehleranfällig)? Witzig. 😉

    P.S.: Wenn du ein Posting editierst und dabei noch etwas anhängst, schreib doch bitte ein "Edit:" davor (sonst ist das zu verwirrend). Danke!



  • OK, scheint zu funktionieren, aber zu dem Problem mit den Zeigern fällt dier nichts ein??

    Sieht insgesamt so aus

    //global_extern_header.hpp
    
    #include "textbuffer.hpp"
    #include "includes_ext.hpp"
    #include "classes_ext.hpp"
    #include "prototypes_ext.hpp"
    
    #ifndef _global_variables_exe_hpp_
    #define _global_variables_exe_hpp_
    
    extern fieldbuffer buffer;
    extern TField Fields[5000];
    extern TUnit unit[100];
    extern std::string name;
    
    #endif
    
    //SpaceColonizing.cpp
    #include "global_extern_header.hpp"
    
    TListElement *Start;
    TListElement *Actual;
    TListElement *Last;
    int hoch=12,breit=26,number, timer=1;
    int pos_director;
    int i;
    TField Fields[5000];
    TField *actual,*n1,*n2,*n3,*n4,*n5,*n6;
    bool first_run=true;
    bool style; // true --> tactical, false --> geographical
    fieldbuffer buffer;
    std::string name;
    
    //------------------------------------------------------------------------------
    int main(void)
    {
      srand(time(0));
      if (first_run)
      {
        init_unit();
        init_fields();
        init_map();
        actual=new TField;
        std::cout<<"                _______________________________________________________________\n";
        std::cout<<"               /  ______________Wilkommen bei Xenos___________________________/\n";
        std::cout<<"              /  /\n";
        std::cout<<"              \\  \\___      _____    ___  __  _____    _____\n";
        std::cout<<"               \\___  \\    / ___ \\  / _ \\/ / / ____\\  / ___ \\\n";
        std::cout<<"                   \\  \\  / /  / / / / \\  / / /      / /__/_/\n";
        std::cout<<" __________________/  / / /__/ / / /__/ / / /____  / /____\n";
        std::cout<<"/____________________/ / _____/  \\_____/  \\_____/  \\_____/\n";
        std::cout<<"      ________        / /  __\n";
        std::cout<<"     / _______\\      /_/  / /                    __           __\n";
        std::cout<<"    / /                  / /                    /_/          /_/\n";
        std::cout<<"   / /         _____    / /  _____    ____     __  ______   __  ____     _____\n";
        std::cout<<"  / /         / ___ \\  / /  / ___ \\  / __ \\   / / /___  /  / / / __ \\   / ___ \\\n";
        std::cout<<" / /         / /  / / / /  / /  / / / / | |  / /  ___/_/  / / / / | |  / /  / /\n";
        std::cout<<"/ /________ / /__/ / / /_ / /__/ / / /  / / / /  / /___  / / / /  / / / /__/ /\n";
        std::cout<<"\\_________/ \\_____/  \\__/ \\_____/ /_/  /_/ /_/  /_____/ /_/ /_/  /_/  \\___  /\n";
        std::cout<<" ________________________________________________________________________/ /\n";
        std::cout<<"/___________________Das Scifi-Strategie-Spiel fr alle Systeme____________/\n";
        std::cout<<"\n";
        std::cout<<"                    Wie m”chtet ihr genannt werden?\n                    Name: ";
        std::cin>>name;
        std::cout<<"\n                    Wo m”chtet ihr beginnen? (0-311)\n                    Feld: ";
        std::cin>>i;
        *actual=Fields[i];
        draw_grid();
        unit[0].enable();
        actual->Unit=&unit[0]; 
      }
      first_run=false;
      draw(actual);
      draw_info(actual);
      buffer.print();
      std::cin>>pos_director;
      switch(pos_director)
      {
        case(8):
          actual=actual->next1;
        case(9):
          actual=actual->next2;
        case(3):
          actual=actual->next3;
        case(2):
          actual=actual->next4;
        case(1):
          actual=actual->next5;
        case(7):
          actual=actual->next6;
        default:
          actual=actual;
      };
      main();
    };
    //------------------------------------------------------------------------------
    /*
     y->
    x
    |
    v
    30
       6
     1    12
       7      18                             6  1  2      O->next1=&(O-1)
     2    13      25                          \ | /       O->next2=&(O+x-1)
       8      19      30                        O         O->next3=&(O+x)
     3    14      25                          / | \       O->next4=&(O+1)
       9      20       1                     5  4  3      O->next5=&(O-x+1)
     4    15      26                                      O->next6=&(O-x)
       10     21       2
     5    16      27                                      if (n>(x*y)){n=n-(x*y);};
       11     22       3
     6    17      28
       12     23       4
     7    18      29
       13     24       5
          19      30
              25       6
                   1
                       7*/
    //------------------------------------------------------------------------------
    
    void init_map()
    {
      Start = new TListElement;
      Start->succsessor = new TListElement;
      Actual = Start;
      while (number=0,number <= (hoch * breit),number++) 
      {
        *Last = *Actual;
        Actual->succsessor = new TListElement;
        *Actual = *Actual->succsessor;
        *Actual->forrunner = *Last;
        *Last->succsessor=*Actual;
        Actual->counter = number;
        *Actual->Field=Fields[number];
        *Start->forrunner=*Actual;
      };
      *Actual->succsessor=*Start;
    };
    
    //------------------------------------------------------------------------------
    
    void init_fields()
    /*
    type=0->  Meadow        FKC = 'Wiese '
    type=1->  Mountain      FKC = ' Berg '
    type=2->  Hills         FKC = 'Hgel '
    type=3->  Sea           FKC = ' Meer '
    type=4->  Forrest       FKC = ' Wald '
    type=5->  Oil           FKC = '  ™l  '
    type=6->  Coast         FKC = 'Kste '
    */
    
    {
      for(int counter=0; counter < 312; counter++)
      {
         Fields[counter].init((rand()%7),1,1,1,1,1.125,0.825,true);
         Fields[counter].set_FKC(convert(Fields[counter].get_type()));
    
         int a,b,c,d,e,f;
         a=counter-1;
         b=counter+hoch-1;
         c=counter+hoch;
         d=counter+1;
         e=counter-hoch+1;
         f=counter-hoch;
         if(a>=(321)){a=a-(312);};
         if(b>=(312)){b=b-(312);};
         if(c>=(312)){c=c-(312);};
         if(d>=(312)){d=d-(312);};
         if(e>=(312)){e=e-(312);};
         if(f>=(312)){f=f-(312);};
         if(a<0){a=a+312;};
         if(b<0){b=b+312;};
         if(c<0){c=c+312;};
         if(d<0){d=d+312;};
         if(e<0){e=e+312;};
         if(f<0){f=f+312;};
         Fields[counter].next1=&Fields[a];
         Fields[counter].next2=&Fields[b];
         Fields[counter].next3=&Fields[c];
         Fields[counter].next4=&Fields[d];
         Fields[counter].next5=&Fields[e];
         Fields[counter].next6=&Fields[f];
         //Fields[0].next1=&Fields[311];
      }
    };
    
    //------------------------------------------------------------------------------
    
    void move_unit(int direction)
    {
    TField *Move_to = new TField;
    switch(direction)
    {
    case(1):
    Move_to = actual->next1;
    case(2):
    Move_to = actual->next2;
    case(3):
    Move_to = actual->next3;
    case(4):
    Move_to = actual->next4;
    case(5):
    Move_to = actual->next5;
    case(6):
    Move_to = actual->next6;
    };
    Move_to->Unit=actual->Unit;
    };
    
    //classes_ext.hpp
    #include "includes_ext.hpp"
    
    /*
       00000000011111111112222222222333333333344444444445555555555666666666677777777778
       12345678901234567890123456789012345678901234567890123456789012345678901234567890
       ________________________________________________________________________________
    01|       ----      ----      ----      ----      ----                             |
    02|      /    \    /    \    /    \    /    \    /    \                            |
    03|  ---- Wald ---- Meer ---- Wald ----Huegel---- Berg                             |
    04| /    \    /    \    /    \    /    \    /    \    /                            |
    05|  Wald ----Huegel---- Berg ---- Berg ---- Wald ----                             |
    06| \    /    \    /    \    /    \    /    \    /    \                            |
    07|  ----Huegel---- Meer ---- Oel  ---- Oel  ----Kueste                            |
    08| /    \    /    \    /    \    /    \    /    \    /                            |
    09| Wiese ---- Berg ---- Oel  ---- Berg ----Wiese ----                             |
    10| \    /    \    /    \    /    \    /    \    /    \                            |
    11|  ---- Berg ---- Wald ---- Oel  ----Huegel----Huegel                            |
    12| /    \    /    \    /    \    /    \    /    \    /                            |
    13|  Berg ---- Wald ----Kueste----Huegel----Wiese ----                             |
    14| \    /    \    /    \    /    \    /    \    /    \                            |
    15|  ----Wiese ---- Wald ---- Meer ---- Berg ---- Wald                             |
    16| /    \    /    \    /    \    /    \    /    \    /                            |
    17|  Berg ---- Wald ----Kueste---- Wald ----Huegel----                             |
    18| \    /    \    /    \    /    \    /    \    /    \                            |
    19|  ----Kueste----Wiese ----Huegel----Huegel---- Meer                             |
    20| /    \    /    \    /    \    /    \    /    \    /                            |
    21|  Berg ----Wiese ---- Oel  ---- Berg ---- Meer ----                             |
    22| \    /    \    /    \    /    \    /    \    /                                 |
    23|  ----      ----      ----      ----      ----                                  |
    24|                                                                                |
    25|________________________________________________________________________________|
    
    */
    //------------------------------------------------------------------------------
    
    class TUnit
    {
      private:          
              int off;
              int def;
              bool attack;
              int health_state;
    
              bool enabled;
      public:
             std::string name;
             void init(std::string name, int off, int def, int health_state, bool attack)
             {
             set_offence(off);
             set_defence(def);
             set_name(name);
             set_attack(attack);
             set_health_state(health_state);     
             }
    
             void set_offence(int NA)
             {
               off=NA;
             };
             int get_offence()
             {
               return(off);
             };
    
             void set_defence(int NA)
             {
               def=NA;
             };
             int get_defence()
             {
               return(def);
             };
    
             void set_name(std::string NA)
             {
               name=NA;
             };
             std::string get_name()
             {
               return(name);
             };
    
             void set_attack(bool NA)
             {
                  attack=NA;
             };
    
             void set_health_state(int NA)
             {
             health_state=NA;
             };
    
             int get_health_state()
             {
             return(health_state);
             };
    
             void enable()
             {
               enabled=true;
             };
    
             void disable()
             {
               enabled=false;
             };
    };
    
    //------------------------------------------------------------------------------
    
    class TField
    {
      private:
              double food;
              double energy;
              double material;
              double data;
              double offence;
              double defence;
              int type;
              double street_type;
              std::string FKC;
              bool suitable;
              std::string additional_context; //for missions only
    
    public:
              TUnit* Unit;
              TField *next1, *next2, *next3, *next4, *next5, *next6;
                                   //       ----      
                                   //      /    \    
                                   //  ----   a  ----   
                                   // /    \    /    \
                                   //    f  ----   b  
                                   // \    /    \    /
                                   //  ----      ----
                                   // /    \    /    \
                                   //    e  ----   s
                                   // \    /    \    /
                                   //  ----   d  ---- 
                                   //      \    /
                                   //       ----       
    
    void init(int t,double f, double e, double m, double d, double off, double def, bool s)
    {
      type=t; food=f; energy=e; material=m; data=d; offence=off; defence=def; suitable=s;
    };
    
    //-------food_count-------------------------------------------------------------
             void set_food(double NA)
             {
               food=NA;
             };
             double get_food()
             {
               return(food);
             };
    
    //-------energy-----------------------------------------------------------------
             void set_energy(double NA)
             {
               energy=NA;
             };
             double get_energy()
             {
               return(energy);
             };
    
    //-------ressources-------------------------------------------------------------
             void set_material(double NA)
             {
               material=NA;
             };
             double get_material()
             {
               return(material);
             };
    
    //-------offence----------------------------------------------------------------
             void set_offence(double NA)
             {
               offence=NA;
             };
             double get_offence()
             {
               return(offence);
             };
    
    //-------defence----------------------------------------------------------------
             void set_defence(double NA)
             {
               defence=NA;
             };
             double get_defence()
             {
               return(defence);
             };
    
    //-------type-------------------------------------------------------------------
             void set_type(int NA)
             {
               type=NA;
             };
             int get_type(void)
             {
               return(type);
             };
    
    //-------Field Key Character----------------------------------------------------
             void set_FKC(std::string NA)
             {
               FKC=NA;
             };
             std::string get_FKC()
             {
               return(FKC);
             };
    };
    
    //------------------------------------------------------------------------------
    
    class TListElement
    {
      public:
      double counter;     
      TListElement *forrunner;
      TListElement *succsessor;
      TField *Field;
    };
    
    //------------------------------------------------------------------------------
    
    struct TInitiator
    {
      TListElement *FirstElement;
    };
    

    So, jetzt steht hier alles, was notwendig sein sollte, wenn du noch was brauchst, du weist ja, wo du es findest!

    Und was das mit der ersten, wenig fehleranfälligen Implementierung angeht, sie hat ja schlieslich nicht funktioniert, wie kann sie da Fehler produzieren??


Anmelden zum Antworten