Parser
-
Hi,
Ich möchte aus einer Datei die folgenden Zahlen auslesen. Mein Problem sind u.a. die Leerzeichen vor dem Doppelpunkt. Als Erkennungsmerkmal sollen aber gerade Leerzeichen (und nicht ": ") dienen.
STATIC PRESSURE : 55790.0230145 [Pa]
STATIC PRESSURE : 94192.1555228 [Pa]
ABSOLUTE MACH NUMBER : 0.318594727252 [-]
ABSOLUTE TOTAL PRESSURE : 59855.3120222 [Pa]Vielen Dank für die Hilfe,
W2K2005
-
W2K2005 schrieb:
Ich möchte einen Parser schreiben, um die Zahlen aus den folgenden Textzeilen zu lesen.
Dann mach das doch.
W2K2005 schrieb:
Vielen Dank für die Hilfe
Kein Problem.
(Wer nicht in der Lage ist konkrete Fragen zu stellen, der hat eigentlich auch keine Antworten verdient ..)
-
du brauchst eventuell ein scanf oder fgetc()/getchar(), um selber zu parsen.
theorie: automatenlehre, finite state machine
-
Reguläre Ausdrücke sollten hier reichen, da braucht man glaube ich keinen vollständigen Parser implementieren:
[A-Z ]+[A-Z] +: +[0-9\.]+ +\[[A-Za-z]+] ^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^^ Bez. Wert Einheit(?)
-
Hi,
vielen Dank für die ersten Tips.
[A-Z ]+[A-Z] +: +[0-9\.]+ +\[[A-Za-z]+]
^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^^
Bez. Wert Einheit(?)Könntest Du das etwas genauer noch einmal ausführen?
Ich könnte natürlich eine Routine schreiben, die alle Zahlen sammelt, sobald sie das erste Leerzeichen findet - aber wie teile ich dieser mit, dass eine Vielzahl von Leerzeichen hintereinander erst einmal zu überlesen sind?
-
Du könntest den String mit strtok() zerlegen und in jeden Teil mit isdigit() überprüfen, ob er (d)eine Zahl enthält - wenn ja, jagst du sscanf("%f") oder atof() über den Textausschnitt.
-
So was einfaches beherrscht sscanf locker.
include <stdio.h> #include <string.h> const char * lines[] = { "STATIC PRESSURE : 55790.0230145 [Pa]", "STATIC PRESSURE : 94192.1555228 [Pa]", "ABSOLUTE MACH NUMBER : 0.318594727252 [-]", "ABSOLUTE TOTAL PRESSURE : 59855.3120222 [Pa]", }; void parse( const char * str) { char name[30]; double value; char unit [20]; sscanf(str, "%[^:]:%lf [%[^]]", name, &value, unit ); if ( name[strlen(name)-1] == ' ' ) name[strlen(name)-1]='\0'; printf("name = '%s', value = %f, unit = %s\n", name, value, unit ); } int main() { int idx; for ( idx = 0; idx < 4; ++idx ) { parse(lines[idx]); } }
mein output:
name = 'STATIC PRESSURE', value = 55790.023015, unit = Pa name = 'STATIC PRESSURE', value = 94192.155523, unit = Pa name = 'ABSOLUTE MACH NUMBER', value = 0.318595, unit = - name = 'ABSOLUTE TOTAL PRESSURE', value = 59855.312022, unit = Pa
Kurt
-
Kann bei diesem Synatax auch eine Sicherheitsabfrage einbauen?
Wie kann man also einen Programmabsturz verhindern, wenn sscanf die Zeile nicht interpretieren kann?
Vielen Dank für die Hilfe.
Das Programm hat mir sehr geholfen.
-
Klar
void parse( const char * str) { char name[30]; double value; char unit [20]; if ( 3 == sscanf(str, "%[^:]:%lf [%[^]]", name, &value, unit ) ) { if ( name[strlen(name)-1] == ' ' ) name[strlen(name)-1]='\0'; printf("name = '%s', value = %f, unit = %s\n", name, value, unit ); } else { printf("error parsing '%s'\n", str ); } }
Kurt
-
Hi,
ich muss noch zwei Nachfragen stellen.
- Wie würdest Du aus einer Datei die jeweilige Textzeile für sscanf einlesen, wenn Du die Zeilenlänge nicht genau absehen kannst. (Meine Zeilen sind nicht unendlich lang; aber ich will die Verwendung einer tmpZeile mit 1000-Zeichen vermeiden.
char tmpZeile[1000]; char test[20]; double i; fPtr = fopen("datenbank.dat", "r"); if (fPtr != NULL) { fgets(fPtr, 100, tmpZeile); // So ??? // tmpZeile = "Benny is 29.15 years old"; sscanf(tmpZeile,"%s %*s %d", test, &i); }
- Aus irgend einem Grund meckert mein Compiler immer an der sscanf-Zeile. Ich weiß beim besten Willen nicht warum. Der Fehler muss etwas mit der Fließkommazahl für i zu tun haben.
FEHLERMEDLUNG: floating point not loaded
Gruß,
W2K2005
-
An der sscanf-zeile hat der compiler nichts herumzumeckern.
"floating point not loaded" ist eine Laufzeit Fehlermeldung.
Der compiler sollte vielmehr an der fgets-zeile herummeckern.
sollte so aussehen:fgets(tmpZeile, 100, fPtr );
Kurt
-
Hi,
ich schicke einmal genau die Zeilen, die bei mir nicht funktionieren.
Die fgets-Zeile hatte ich noch gar nicht implementiert.int getCoordinates(char filename[], sCoords *p_Coords, int maxI, int maxJ) { int ij=0; double x; double y; char string[512] = "STATIC PRESSURE : 29.0 [pa]"; char tmp[20], tmp2[20]; FILE *fPtr; // Öffne die Gitterdatei, um die Kontrollparameter einzulesen fPtr = fopen(filename, "r"); if (fPtr != NULL) { //do { // Anzahl der Punkte in i und j Richtung einlesen // fgets(string, 100, fPtr); sscanf(string, "%[^:]:%lf [%[^]]", tmp, &y, tmp2); //ij = ij + 1; //} while (ij < maxI*maxJ); fclose(fPtr); return 1; } else { // Datei konnte nicht zum Lesen geöffnet werden return 0; } }
-
Also am sscanf liegts nicht wenn irgendwas nicht funktioniert.
Wenn du immer noch den laufzeitfehler "floating point not loaded" bekommst dann musst du wahrscheinlich irgend ein library dazulinken.
Kurt
-
Könnte der Fehler in Verbindung mit MS Visual Studio .NET stehen?
Ich habe vorher immer mit Version 6 gearbeitet. Allerdings wüsste ich auch nicht welche Bibliothek ich noch einbinden muss. Das merkwürdige an dem Problem ist, dass die Anweisungen funktionierten, sobald ich aus der double-Variable y einen int-Wert gemacht habe.
-
-
Hallo Kurt,
noch eine letzte Frage zu Deinem Code:
sscanf(str, "%[^:]:%lf [%[^]]", name, &value, unit )
Könntest Du bitte noch einmal erklären was Du mit den Ausdrücken "%[^:]:" und "[%[^]]" erreichst.
Vielen Dank.
-
der Ausdruck "%[12345abcd]" bedeutet lese solange in einen string solange irgend ein zeichen vorkommt das zwischen den '[' und ']' steht.
das ^ invertiert die Bedeutung.
"%[^:]" lese solange in den string bis ein ':' gefunden wird.
Kurt
-
int parse(char *string, char *name, double *value, char *unit) { if (3 == sscanf(string, "%[^:]:%lf [%[^]]", name, &value, unit)) { if (name[strlen(name)-1] == ' ' ) { name[strlen(name)-1]='\0'; } return 1; } else { printf("> Error parsing. "); return 0; } }
Hi,
wenn ich versuche über den nachfolgenden Aufruf eine Zeile in *string zu parsen, bricht das Programm immer mit einem Ausnahmefehler zusammen.
// Textzeile auslesen fgets(string, max, fPtr); // string = STATIC PRESSURE : 55790.0230145 [Pa] (not reduced quantity) RetVal = parse(string, name, &value, unit);
Ich weiß nicht so recht wonach ich suchen soll, denn ich erhalte nicht einmal eine Fehlermeldung...
Gruß,
W2K2005
-
In meinem Beispiel war name nur 30 zeichen lang. Wenn das noch immer so ist dan krachts.
BTW du hast jetzt mehrere lehrzeichen vor dem ':' dann wäre wahrscheinlichint parse(char *string, char *name, double *value, char *unit) { if (3 == sscanf(string, "%[^:]:%lf [%[^]]", name, &value, unit)) { while ( strlen(name) && (name[strlen(name)-1] == ' ' )) name[strlen(name)-1]='\0'; return 1; } else { printf("> Error parsing. "); return 0; } }
Kurt
-
Hey,
Du bist echt gut!
Also, mittlerweile läuft das Programm - nur der Wert in value kommt noch nicht an...
Mal gucken, wer schneller drauf kommt!P.S.:
Die Leerzeichen waren eigentlich schon die ganze Zeit dabei - diese werden aber vom Forum geschluckt!!!
Ich hatte nur etwas andere Zeilen als erstes gepostet.
Allgemein sieht mein Inhalt so aus:STATIC PRESSURE : 55790.0230145 [Pa] STATIC PRESSURE : 55790.0230145 [Pa] (not reduced quantity) STATIC PRESSURE : 94192.1555228 [Pa] (reduced quantity) ABSOLUTE MACH NUMBER : 0.318594727252 [-] (not reduced quantity)