Überprüfung der Formatierung einer Textdatei beim Einlesen



  • GuitarKing schrieb:

    Nur wie schaue ich jetzt, dass diese Formatierung auch stimmt? Sollte sie nicht stimmen, soll ein Fehlercode ausgegeben werden.

    sscanf, fscanf geben die Anzahl der konvertierten Elemente zurück, die kannst du prüfen. Wenn die erwartete Anzahl nicht stimmt, kannst du nen Fehlercode ausgeben.



  • DirkB schrieb:

    Mit fscanf erst den Bezeichner lesen und davon abhängig dann den Rest.

    Nein.
    Wenn die Formate fest sind wie beschrieben, dann 3 sscanf-Formatstrings dafür und über sscanf-Rückgabe-Auswertung die Zuordnung zu den Typen vornehmen.



  • GuitarKing schrieb:

    rectangle id="1" color="000033" x="0" y="0" width="640" height="480"
    

    Mein Gott, was ist denn daran so schwer, einfach diese Konstanz des Datenformates auszunutzen und identisch in einen Formatstring zu übertragen?

    char *s="rectangle id=\"1\" color=\"000033\" x=\"0\" y=\"0\" width=\"640\" height=\"480\"";
    unsigned a,b,c,d,e,f;
    if( 6==sscanf(s,"rectangle id=\"%u\" color=\"%x\" x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\"",&a,&b,&c,&d,&e,&f) )
      puts("OK");
    


  • Wutz schrieb:

    Mein Gott, was ist denn daran so schwer, einfach diese Konstanz des Datenformates auszunutzen und identisch in einen Formatstring zu übertragen?

    Die Idee ist gut. 👍
    Die könnte von mir sein. :p



  • Wobei hierbei sogar derselbe Formatstring für sscanf auch für (s)printf zu gebrauchen wäre, im Sinne einer Wiederverwendung.



  • Oke danke, hab das Problem mittlerweile gelöst. Nun hab ich aber ein neues.
    Und zwar habe ich ein struct definiert mit einigen variablen.
    In meiner main Funktion speichere ich eine eingelesene Variable einer Datei in eine Struct variable z.B.:

    pos_x.x = x_r;
    

    D.h. "x_r" ist die eingelesene Variable und die wird in "x" über "pos_x" in das struct gespeichert. Soweit so gut.

    Nun habe ich eine andere Funktion (getColor), in der ich eine eingelesene hexadezimal codierte RGB Farbe (übergabe an "hex_color") mit 6 Stellen von der main Funktion aufteile, um die einzelnen Farbanteile herauszufischen (mit bitshifting etc.).

    void getColor(int hex_color)
    {
      int count;
      int pos;
    
      struct FormProperties color; //definition of variable "color" of 
                                   //struct type "FormProperties"
    
      for(count=COUNTVALUE1; count<=COUNTVALUE3; count += COUNTVALUE2) //rightshift  
      {                                                                //two nibble 
    
        pos = ((hex_color>>count) & 0xff); 
    
        if(count == COUNTVALUE1)
        {
          color.color_blue = pos;
    
         //printf("Color blue = %x\n", pos);
        }
        else if(count == COUNTVALUE2)
        {
          color.color_green = pos;
          //printf("Color green = %x\n", pos);
        }
        else  if(count == COUNTVALUE3)
        {
          color.color_red = pos;
          //printf("Color red = %x\n", pos);
        }
      }
    
    }
    

    Diese Farbanteile von "pos" will ich wieder jeweils in eine struct Variable (color_red, color_green, color_blue) mit der gleichen Methode wie oben genannt speichern und in der main Funktion testweise ausgeben, um zu sehen, ob das über das struct funktioniert (da ich später diese Variablen an eine Liste weitergeben muss, wo die variablen dann weiterverarbeitet werden). Das tut es jedoch nicht. D.h. er würde mir das in der struct variable gespeicherte nur in der jeweiligen Funktion ausgeben, in der ich auch wirklich einen Wert in die Struct Variable speichere. Wieso wird nichts "global" in die struct Variable von der Funktion getColor gespeichert, sodass ich von überall darauf zugreifen kann? Mach ich da einen Denkfehler?



  • GuitarKing schrieb:

    D.h. "x_r" ist die eingelesene Variable und die wird in "x" über "pos_x" in das struct gespeichert. Soweit so gut.

    Soweit so gut? Wozu der Umweg über eine Variable, warum nicht direkt in der Struktur speichern?

    GuitarKing schrieb:

    Nun habe ich eine andere Funktion (getColor), in der ich eine eingelesene hexadezimal codierte RGB Farbe (übergabe an "hex_color") mit 6 Stellen von der main Funktion aufteile, um die einzelnen Farbanteile herauszufischen (mit bitshifting etc.).

    Dafür brauchst du weder for Schleife noch if/else Anweisungen.

    unsigned hex_color = 0xAABBCCDD;
    	printf ( "%x %x %x %x\n", hex_color>>24, (hex_color>>16) & 0x00FF, (hex_color >> 8) & 0x00FF, hex_color & 0x00FF );
    

    GuitarKing schrieb:

    Diese Farbanteile von "pos" will ich wieder jeweils in eine struct Variable (color_red, color_green, color_blue) mit der gleichen Methode wie oben genannt speichern und in der main Funktion testweise ausgeben, um zu sehen, ob das über das struct funktioniert (da ich später diese Variablen an eine Liste weitergeben muss, wo die variablen dann weiterverarbeitet werden). Das tut es jedoch nicht. D.h. er würde mir das in der struct variable gespeicherte nur in der jeweiligen Funktion ausgeben, in der ich auch wirklich einen Wert in die Struct Variable speichere. Wieso wird nichts "global" in die struct Variable von der Funktion getColor gespeichert, sodass ich von überall darauf zugreifen kann? Mach ich da einen Denkfehler?

    Struktur von der Funktion zurückgeben lassen oder noch besser einen Zeiger übergeben.

    struct FormProperties getColor(unsigned hex_color)
    {
    	struct FormProperties color;
    
    	// .... wie auch immer ...
    	return color;
    }
    
    void getColor ( struct FormProperties* pcolor, unsigned hex_color )
    {
    	pcolor->color_blue = ...
    	// .... wie auch immer ...
    	return;
    }
    


  • Weil die Variable lokal ist (Zeile 6)
    Nutze den Rückgabewert der Funktion.



  • DirkB schrieb:

    Weil die Variable lokal ist (Zeile 6)
    Nutze den Rückgabewert der Funktion.

    Stimmt zum Teil. Ich habe es in Zeile 6 unnötigerweise nochmal definiert.
    In Wirklichkeit habe ich die Variable "color" schon im struct ganz zu beginn des Programmes (natürlich außeralb der main) deklariert.

    struct FormProperties
    {
      //.....
    
    } ...,color, ...;
    

    Deswegen sollte es doch funktionieren hab ich mir gedacht.

    CJosef schrieb:

    GuitarKing schrieb:

    D.h. "x_r" ist die eingelesene Variable und die wird in "x" über "pos_x" in das struct gespeichert. Soweit so gut.

    Soweit so gut? Wozu der Umweg über eine Variable, warum nicht direkt in der Struktur speichern?

    Wie? Das Speichern eines Wertes in eine Strukt Variable funktioniert doch nur so oder?

    CJosef schrieb:

    GuitarKing schrieb:

    Nun habe ich eine andere Funktion (getColor), in der ich eine eingelesene hexadezimal codierte RGB Farbe (übergabe an "hex_color") mit 6 Stellen von der main Funktion aufteile, um die einzelnen Farbanteile herauszufischen (mit bitshifting etc.).

    Dafür brauchst du weder for Schleife noch if/else Anweisungen.

    unsigned hex_color = 0xAABBCCDD;
    	printf ( "%x %x %x %x\n", hex_color>>24, (hex_color>>16) & 0x00FF, (hex_color >> 8) & 0x00FF, hex_color & 0x00FF );
    

    Ich möchte ja die einzelnen Teile von "hex_color" in einzelne Farb Variablen speichern. So gebe ich sie ja nur aus.
    Wie gesagt, ich bin mehr oder weniger noch Anfänger 😉



  • GuitarKing schrieb:

    Deswegen sollte es doch funktionieren hab ich mir gedacht.

    Es wird in die lokale Variable geschrieben, die globale bleibt unberücksichtigt.

    CJosef schrieb:

    GuitarKing schrieb:

    D.h. "x_r" ist die eingelesene Variable und die wird in "x" über "pos_x" in das struct gespeichert. Soweit so gut.

    Soweit so gut? Wozu der Umweg über eine Variable, warum nicht direkt in der Struktur speichern?

    GuitarKing schrieb:

    Wie? Das Speichern eines Wertes in eine Strukt Variable funktioniert doch nur so oder?

    Wenn der Wert aus einer Datei kommt, kann er gleich in der Strukturvariable landen, ohne eine Zwischenvariable.

    GuitarKing schrieb:

    Ich möchte ja die einzelnen Teile von "hex_color" in einzelne Farb Variablen speichern. So gebe ich sie ja nur aus.
    Wie gesagt, ich bin mehr oder weniger noch Anfänger 😉

    Die Werte, die printf ausgibt kann man auch speichern

    unsigned farbwert8bit = (hex_color>>16) & 0x00FF;
    


  • Und wie speichere ich den wert dann in die Globale Variable?

    CJosef schrieb:

    GuitarKing schrieb:

    Wie? Das Speichern eines Wertes in eine Strukt Variable funktioniert doch nur so oder?

    Wenn der Wert aus einer Datei kommt, kann er gleich in der Strukturvariable landen, ohne eine Zwischenvariable.

    Also, ich möchte einfach meine eingescannten Farbanteile (in der extra Funktion) Global in mein "struct FormProperties" speichern, von dem aus dann die Variable weitergegeben und verarbeitet werden kann. Wie kann ich das realisieren?
    Kann sein, dass ich ein wenig auf der Leitung stehe. Allerdings sitze ich schon den ganzen Tag am Programm und versuche diverse Probleme zu lösen. Verzeiht mir 😉



  • Ganz einfach, entferne die lokale Variable color, damit die globale Variable color sichtbar wird.
    Und lies dir das Kapitel deines Lehrbuchs über die Sichtbarkeit von Variablen durch.



  • Kannst du interessehalber die Aufgabenstellung posten?



  • In deinem eigenen Interesse: Verzichte auf globale Variablen.
    Die machen meist nur Ärger.

    Du kannst deine Farbwerte auch gleich in die Variablen einlesen:

    char *farbe = "1144aa";
    int r,g,b;
    sscanf(farbe,"%2x%2x%2x",&r,&g,&b);
    


  • An alle schonmal danke für eure Hilfe!
    Ich bin jetzt zum Schluss gekommen, dass die Farbanteile doch nicht aufgeteilt werden müssen. Sie werden einfach gleich so wie sie daher kommen als unsigned int behandelt und weiter verarbeitet. Das macht die ganze Sache natürlich viel einfacher.
    Trotzdem hab ich wieder eine Frage 😉 Und zwar, gilt es, die verschiedenen ID der Formen, die eingelesen werden, auf ihre Existenz zu überprüfen. Also ob sie schon vorhanden sind oder nicht. Sobald eine oder mehrere IDs mehrfach vorommen, soll ein Fehler ausgegeben werden. Ich weiß, wie man Strings auf gewisse Zeichen etc. überprüfen kann, nur ist zu bedenken, dass das Ganze recht dynamisch sein muss, d.h. es können beliebig viele Formen und entsprechend beliebig viele IDs daher kommen. Also ich schätze mal, ich überprüf das am Besten in den Structs, da ja immer die selbe Reihenfolge Einlesen einer Zeile -> speichern in Struct -> übergabe an Weiterverarbeitung gilt. D.h. ich müsste die IDs irgendwie im Struct überprüfen, wenn sie hereinkommen. Oder? Wie mach' ich das am Besten?

    Zur Allgemeinen Aufgabenstellung:
    Eine Eingabedatei enthält eine textuelle Beschreibung des Bildes. Jede Zeile beschreibt dabei entweder ein Rechteck, einen Kreis oder ein Dreieck das vollständig mit der angegebenen Farbe ausgefüllt ist.Die Werte innerhalb der Anführungszeichen sind dabei beliebig wählbar, das restliche Format bleibt jedoch immer gleich. Es kann sogar die hier angegebene Reihenfolge der einzelnen Eigenschaften als gegeben vorausgesetzt werden.
    Die ID ist eine eindeutige vorzeichenlose 32bit Ganzzahl. Wenn sich zwei Objekte überschneiden, soll immer das Objekt mit der höheren ID das andere Objekt verdecken. Die Farbe wird als 6-stellige Hexadezimalzahl angegeben, wobei die ersten beiden Stellen den Rot-Anteil beschreiben, die beiden mittleren Stellen den Grün-Anteil und die letzten beiden Stellen den Blau-Anteil.
    Die Position des Objekts wird über eine ganzzahlige x und y Koordinate angegeben. Der Koordinatenursprung liegt in der linken oberen Ecke des Bildes. Die Koordinaten können auch negativ sein, die Werte für die Breite und Höhe des Rechtecks bzw. für den Radius des Kreises müssen jedoch positiv sein.

    Soweit das Wichtigste.

    Mfg


Anmelden zum Antworten