Object auslesen.



  • Ich Speicher ein paar Objekte in einer file.
    Das schaut so aus

    PictureBegin
    CIRCLE (255/255/0) 5 5 (100,100) 30
    LINE (255/0/0) 5 10 (100,100) (200,200)
    POINT (255/0/0) 0 (100,100)
    TEXT (0/0/0) 10 30 (20,40) 0 Test
    CIRCLE (255/255/0) 5 5 (100,100) 30
    PictureEnd

    Nun möchte ich das wieder einlesen. Aber das funktioniert nicht. Ich weiß auch warum aber nicht geht. Aber ich komm nicht auf die Lösung.

    Ich versuche mal meine Vorgehensweise am POINT darzustellen.

    In Datei Schreibfunktion
    void Point::write(ostream& strm) const
    {
       strm << "   POINT "<< "(" <<(int)color.getRed() << "/" << (int)color.getGreen() << "/" << (int)color.getBlue() << ") " << style << " " << xy << endl;
    }
    Aus Datei lese Funktion.
    void Point::read(istream& strm)
    {
      int red,green,blue,style;
      strm >> red >> green >> blue >> style >> xy;
      this->style=(POINTSTYLE)style;
      Color c(red,green,blue);
      setColor(c);	 
    }
    

    Der strm der read funktion passt ja nicht weil da Zeichen wie ()/ drin sind. Oder irre ich mich da?

    Hier noch meine Load Function. Die funktioniert soweit recht gut bis auf das sie noch nix läd.

    Shape& Picture::load(char* file)
    {
        // Datei oeffnen
        ifstream load;
        load.open(file, ios::in);
    
        if (!load.good())//Pruefen ob sich Datei oeffnen laesst
        {
          cerr << "Datei -"<<file<<"- kann nicht geoeffnet werden" << endl <<endl;
          return *this;
        }
    
        //String mit \0 fuellen
        char saveDatei[1000];
        for (int i=0; i<1000; i++)
        {
          saveDatei[i]='\0';
        }
        //erstes Wort aus Datei lesen
        load >> saveDatei;
        if(!strcmp (saveDatei, "PictureBegin") ==0 )//Prüfen ob in der Datei ein Picture
        {					//Objekt vorahnden ist
          cout << "Kein Bild in der Datei!" << endl;
          return *this;
        }
        while(!load.eof() )
        {
          if (strcmp (saveDatei, "TEXT")==0)  //Nach "Text" suchen
          {
            printf("Habe TEXT gefunden\n");
    		 //Text* te = new Text(Coord(20,40),0,10,30,Black,"Test");
            //load >> *te;
            //this->add(te);
          }
          else if (strcmp (saveDatei, "POINT")==0)  //Nach "Point" suchen
          {
    		printf("Habe POINT gefunden\n");
           // Point* po = new Point(Coord(100,100),Red,CROSS);
           // load >> *po;
           // this->add(po);
          }
          else if (strcmp (saveDatei, "LINE")==0)  //Nach "Line" suchen
          {
    		printf("Habe LINE gefunden\n"); 
          //  Line* li = new Line(Coord(100,100),Coord(200,200),Green,_LONG_DASH,10);
          //  load >> *li;
          //  this->add(li);
          }
          else if (strcmp (saveDatei, "CIRCLE")==0)  //Nach "Circle" suchen
          {
    		  printf("Habe CIRCLE gefunden\n"); 
          //  Circle* ci = new Circle(Coord(100,100),30,Yellow,_LONG_DASH,5);
          //  load >> *ci;
          //  this->add(ci);
          }
          else if (strcmp (saveDatei, "PictureBegin")==0)
          {
          	//Bild im BIld
           }
           //String mit \0 fuellen
           for (int i=0; i<1000; i++)
           {
              saveDatei[i]='\0';
           }
           //Naechstes Wort laden
           load >> saveDatei;
        }
    
        load.close();
    
        return *this;
    }
    


  • Hi,

    Der strm der read funktion passt ja nicht weil da Zeichen wie ()/ drin sind. Oder irre ich mich da?

    ja, so ist es. Außerdem würde ich dir zu einem einheitlichen Trennzeichen raten, etwa # oder $.

    MfG

    GPC



  • Also zuerst mußt du wissen, WAS du da einlesen willst (das geht, indem du den ersten Teil der Zeile bis zum ersten Whitespace einliest und daraufhin entscheidest, was das nächste Objekt sein soll). Dann legst du per new ein Objekt des richtigen Typs an und rufst dessen Einlesemethode auf.

    Diese Methode kann per strm.get() die Zwischenzeichen lesen und dazwischen per >> die einzelnen Elemente des Punktes einlesen:

    void Point::read(istream& strm)
    {
      char ch;
      //wir starten am ( der Zeile
      strm.get(ch);if(ch!='(') return;
      int red,green,blue,style;
      strm>>red>>ch>>green>>ch>>blue;
      strm.get(ch);if(ch;!')') return;
      strm>>style>>skipws;
      ...
    
      setColor(Color(red,green,blue));
      this->style = (POINTSTYLE) style;
      ...
    }
    


  • Hat super Funktioniert.
    Hab paar Veränderrungen vorgenommen und stoße nun auf ein weiteres Problem.

    Der Stream aus em geselen wird schaut so aus.
    POINT (123/231/122) 0 (2,111)
    Die 0 Spielgelt den Style wieder.

    [cpp]void Point::read(istream& strm)
    {
      printf("Bin in POINT::read\n");
      int red,green,blue;
      char ch;
      red=blue=green=0;	
      while(strm.get(ch))
      {
    	  if(ch=='(')
    	  {
    		  strm>>red>>ch>>green>>ch>>blue;
    		  break;
    	  }
      }
      strm.get(ch);if(ch!=')') return;
    [b]strm>>style; // Hier liegt der Fehler[/b]
      strm>>xy;
      this->style=CROSS; // Workarround für Style
      Color c(red,green,blue);
      setColor(c);	 
    }[/cpp]
    

    Die Variable Style ist von Type POINTSTYLE

    typedef enum 
    { 
          CROSS, CIRCLE, PIXEL  
    } POINTSTYLE;
    

    Fehlermeldung vom Compiler

    Point.cpp: In member function »virtual void Point::read(std::istream&)«:
    Point.cpp:56: Fehler: no match für »operator>>« in »strm >> ((Point*)this)->Poin t::style«

    Irgendwie verstehe ich nicht warum der den operator bein nem enum anmekert.

    Noch ne frage.
    Wie bekomme ich anstatt 0 den Wert CROSS in die Datei?



  • Es gibt keine Einles-Operationen für Enum's - d.h. du müsstest 'style' als int einlesen und dann in einen POINTSTYLE casten.

    (die Alternative mit der Text-Darstellung benötigt eine Stringtabelle, mit der du zwischen dem Eingabetext (als String) und dem zugehörigen enum-Wert übersetzen kannst)


Anmelden zum Antworten