ASCII Daten mit N-Spalten aus Textdatei lesen
-
Hallo,
ich möchte gerne aus einer Textdatei Zahlenwerte auslesen, die durch Leerzeichen oder Tabulator voneinander getrennt sind. Im Prinzip weiß ich wie das geht, wenn in der Zeile beispielsweise 3 Informationen stehen.
Aber mir ist nicht klar, wie ich vorzugehen habe, wenn die Anzahl der Elemente pro Zeile nicht vorab bekannt sind und bei der Programmierung berücksichtigt werden können.Für Ideen bin ich sehr dankbar.
-
Hol dir jede einzelne Zeile in ein Array, dann kannste dir locker die Daten holen.
Sprich:while(!File.eof()) { getline(..) //Blablabla }
(Müsste halt auf C angepasst werden)
-
Meinst Du, dass ich die Zeile als String einlesen soll, um diese dann mit einer selbstgeschriebenen Funktion in einzelne Zahlen zu zerhacken?
-
lies einfach die zahlen ein, bis ein newline kommt, extra nen string einlesen ist doch unnötig.
-
und wie? ich weiß doch nicht, ob die zeile so
12.12342 14E+5 28.000 -12312
oder so
12.12342 14E+5 28.000 -12312 134.456 123.00002011 -9999 20000
aussieht. ?!?!?!
-
Phil270307 schrieb:
und wie? ich weiß doch nicht, ob die zeile so
12.12342 14E+5 28.000 -12312
oder so
12.12342 14E+5 28.000 -12312 134.456 123.00002011 -9999 20000
aussieht. ?!?!?!
Das ist Wurscht. Ich kenne deine Kenntnisse in C nicht, aber ich gehe mal davon aus, das du mit Dateibearbeitung vertraut bist(fopen, fgetc, fscanf, etc.).
Schreibst du dir ein Makro:#define num_begin(x) x >= '0' && x <= '9' || x == '.' || x == '-' || x == '+'
Dann guckst du in jedes Zeichen rein und fragst mit Hilfe des Makros ab, ob das Zeichen der Beginn einer Zahl ist; wenn ja, spuckst du es wieder aus und lässt fscanf den Job machen:
while ( (c = fgetc(fp)) != EOF ) { if (num_begin(c)) { ungetc(c,fp); // Ausspucken if ( 1 != fscanf(fp, "%lf", &num)) { // Fehlerbehandlung ...
¿Comprende, señor?
MfG,
Mr. C
-
Hallo,
ich verstehe, was Du mir geschrieben hast und möchte noch eine weiterführende Frage stellen:
Die Datei, welche ich einlese, besitzt auch noch Informationen, die über dem Zahlen stehen und welche ich einlesen muss.xxxxxxxxxxxxx xxxxxxxxx yyyyyyyyyyyyy yyyyyyyyyyyyyyyyyyyyyyyy xxxxxxxxxxxxx xxxxxxxxx="Info" 123.4 123.45 321.45 123.4 123.45 321.45 123.4 123.45 321.45 123.4 123.45 321.45 xxxxxxxxxxxxxxx xxxxxxxxx yyyyyyyyyyyyyy yyyyyyyyyyyyyyyyyyyyyyyy xxxxxxxxxxxxxxx xxxxxxxxx="Info" 1.E-5 20.005 222.00000 -45.678 -220. 20E+0005 2.E-5 20.005 122.00000 -45.678 -220. 40E+0005 3.E-5 20.005 422.00000 -45.678 -220. 30E+0005 1.E-5 20.005 322.00000 -45.678 -220. 50E+0005 ...
Daher habe ich die Zeile zuerst mit "fgets" in den Buffer gelesen, um dann mit einer Suchfunktion zu prüfen, ob bestimmte Keywords in dem String enthalten sind.
Wenn ja, habe ich diese extrahiert;
Wenn nein, wurde die Zeile ignoriert.Wenn ich nun den Ansatz von Dir noch hinzufügen möchte, müsste ich doch Deinen Code über den Buffer "line" laufen lassen. Korrekt? Ich bin nicht sicher, ob das in C so funktioniert:
#define num_begin(x) x >= '0' && x <= '9' || x == '.' || x == '-' || x == '+' int c; int flag_numeric = 0; double num; char *cc; char line[const_strlen1]; do { fgets(line, const_strlen1, fp); line[strlen(line)-1] = '\0'; /* ... */ /* Durchsuche den String mit Hilfe geeigneter Funktionen, ob bestimmte Keywords vorkommen */ /* Wenn kein Keyword gefunden wurde, dann ist flag_numeric = 1*/ /* ... */ if (flag_numeric == 1) { while ( (c = getc(line)) != '\0' ) { if (num_begin(c)) { cc = &line[c]; if ( 1 != scanf(cc, "%lf", &num)) else { // Fehlerbehandlung ... } } } } while (!feof(fp));
Macht das Sinn?
-
Phil270307 schrieb:
Macht das Sinn?
Nein, denn die Funktion getc arbeitet auf einem Steam vom Typ FILE* und scanf liest von stdin.
Statt getc kannst du direkt line[i] abfragen und anstatt scanf kannst du sscanf benutzen.
Das Makro num_begin(x) brauchst du dann gar nicht mehr und kannst jeweils bis zum nächsten Leerzeichen gehen, dann wieder sscanf aufrufen, bis string-Ende.
-
Mr. C schrieb:
... und kannst jeweils bis zum nächsten Leerzeichen gehen, dann wieder sscanf aufrufen, bis string-Ende.
Oder strtod nehmen, ist eventuell noch etwas einfacher.