C File Ein-Ausgabe

FreddyMercury

Rear Admiral
Registriert
Dez. 2002
Beiträge
5.414
Hi Leute,

hab ein kleines Problem. Ich will ne Textdatei einlesen, die nen Zirkel, Dreieck und ein paar andere Werte wiedergeben kann und die soll so aussehen:
Code:
4
54321 3 80.0 185.0 20 10
346224 2 105.0 178.0 10
12 1 120.0 190.0 50
8987654 4 207.0 145.0 244.0 155.0 232.0 180.0

Die erste Zeile (in dem fall 4) zeigt an wieviele Objekte in der Datei vorhanden sind.
Die folgenden Zeilen daraufhin sind dann die Objekte. Der erste Wert ist die objektID (54321 z.B.) und der zweite Wert ist der Objekt typ. Nach 54321 die 3 ist also ein Zirkel. Der Rest sind halt die Mase (sorry hab kein sz auf meiner Tastatur).

Ich weiss wie ich die Datei komplett einlesen kann und ich kann auch zeilenweise einlesen. Jetzt weiss ich allerdings nicht, wie ich die Werte Zeilenweise einlesen und an einzelne variablen in structs uebergeben kann. Waere super wenn mir da jemand eine Hilfe geben koennte.
Momentan benutze ich ein simples fgets() in einem while loop
Code:
while( fgets( array, sizeof(array), fp ) != NULL ) {
    printf( "%s", array );
}
 
Also ich würde hier mit fgetc() in ein char-Array einlesen. Das char-Array wird vor jedem Durchgang mittels memset() komplett mit \0 (=String-Terminator) befüllt und es muss sichergestellt werden, dass IMMER mind. ein \0 am Ende des char-Arrays verbleibt. Gelesen wird bis entweder EOF, Leerzeichen oder Linefeed erreicht wurde. Anschließend wird das char-Array mit atoi() bzw. atof() in Integer/Double umgewandelt und in dein Struct eingefügt.
In etwa so (ungetestet und ohne Behandlung deiner ersten Zeile):
Code:
char tmp[16];
char c;
int newObject = 1;
int found = 0;
int break = 0;
do{
  memset(tmp,0x0,16);
  for(i= 0; i < 15; ++i){
    c = fgetc(file);
    if(c == EOF) {       // aus Schleife raus, parsen und beenden
      break = 1;
      break;
    }
    if (c == ' ') break;   // nächstes Datenfeld
    if(c == '\n' || c == '\r'){    // neue Zeile => neues Struct
      newObject = 1;
      break;
    }
    tmp[i] = c;
  }
  if(i != 0){ // erhaltenes char-Array umwandeln
    if(newObject == 1){
        // neues Struct initialisieren
        newObject = 0;
    }
    // hier das Struct mittels atoi() für die ObjektID bzw. atof() für die Maße befüllen; evtl. brauchst da noch nen counter dazu
    ++found;
  }
} while (break == 0);
Bissel ungünstig ist dass der Objecttyp erst als zweites Zeichen kommt. Da musst du halt evtl. vorher in ner Variablen die ObjektID zwischenpuffern noch.

Generell wären natürlich Serialisierungswerkzeuge (wie sie z.B. in der Boost-Library (C++) enthalten sind) wesentlich einfacher.
 
Zuletzt bearbeitet:
Danke, ich werds mir mal ansehen. Werd versuchen es weitgehendst auf dem laufenden zu halten. Dumm ist das der Objecttyp immer eine andere Einheit sein kann, je nachdem wie der Wert von 0 - 4 Schwankt.
Kann ich mit atoi oder atof in dem Char Array bestimmte Werte in Integer oder Double umwandeln oder werden alle umgewandelt? Weil ich hab ca. 16 verschiedene Variablen in die ich die Werte einzeln reinspeichern will, aber halt nach dem Schema. Und ich nehme richtig an das ich newObject mit nem struct ersetzen sollte?
 
Zuletzt bearbeitet:
Schau halt in die Doku von atoi bzw. atof. atoi:
The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.
Der wandelt also um was da ist, stoppt aber wenn er nach den Zahlen Buchstaben oder Whitespace findet. Deshalb muss auch das Char-Array entsprechend vorbereitet sein (oder eben ein entsprechender Pointer existieren).
newObject ist bei mir nur eine Hilfsvariable um festzustellen, dass jetzt ein neues Objekt erstellt werden muss (eben bei einer neuen Zeile). Wie du das genau befüllst musst du schon selber machen. Ein counter wäre aber wohl praktisch (siehe mein Kommentar in der viertletzten Codezeile) damit du weißt welcher Wert in deinem Struct jetzt befüllt werden muss.
 
Zurück
Oben