parsen von ASCII Dateien
parsen von ASCII Dateien
Hallo!
Ich bin seit ca. 6 Wochen mit C unterwegs, was (auch Dank dieses Forums) gut klappt. Jetzt stehe ich aber vor folgendem Problem:
Ich möchte aus einer ASCII Date Werte lesen, wobei die Werte in Spalten ausgerichtet sind, d.h. der Wert steht z.B. in sen Spalten 1-8 oder 9-32 usw.
Da ich nicht davon ausgehen kann, daß alle Werte weniger als 8 Stellen haben oder alle Werte rechtsbündig stehen, komme ich mit strtok nicht weiter, da es sein kann, daß zwischen zwei Werten kein Leerzeichen vorkommt.
Was ich gerne programmieren würde, wäre eine Funktionread_int_from_line (s.u.), der ich die Zeile und die Spalten, aus denen ich die Werte lesen will (von - bis) gebe und den dort gelesenen Wert zurückbekomme:
while(!feof(file))
{
fgets(zeile,80,zeile);
von_spalte=1;
bis_spalte=11;
/* lesesn der Spalte 1 bis 11 und als int zurückgeben*/
wert_1=read_int_from_line( zeile, von_spalte, bis_spalte);}
Kann mir da jemand einen Tip geben wie man das am schlauesten macht?
Danke!
Ich bin seit ca. 6 Wochen mit C unterwegs, was (auch Dank dieses Forums) gut klappt. Jetzt stehe ich aber vor folgendem Problem:
Ich möchte aus einer ASCII Date Werte lesen, wobei die Werte in Spalten ausgerichtet sind, d.h. der Wert steht z.B. in sen Spalten 1-8 oder 9-32 usw.
Da ich nicht davon ausgehen kann, daß alle Werte weniger als 8 Stellen haben oder alle Werte rechtsbündig stehen, komme ich mit strtok nicht weiter, da es sein kann, daß zwischen zwei Werten kein Leerzeichen vorkommt.
Was ich gerne programmieren würde, wäre eine Funktionread_int_from_line (s.u.), der ich die Zeile und die Spalten, aus denen ich die Werte lesen will (von - bis) gebe und den dort gelesenen Wert zurückbekomme:
while(!feof(file))
{
fgets(zeile,80,zeile);
von_spalte=1;
bis_spalte=11;
/* lesesn der Spalte 1 bis 11 und als int zurückgeben*/
wert_1=read_int_from_line( zeile, von_spalte, bis_spalte);}
Kann mir da jemand einen Tip geben wie man das am schlauesten macht?
Danke!
"21" ist nur die halbe Wahrheit...
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: parsen von ASCII Dateien
Dann erstmal ein sechs Wochen verspätetes Willkommen im Forum.Bruno hat geschrieben:Ich bin seit ca. 6 Wochen mit C unterwegs, was (auch Dank dieses Forums) gut klappt.

Die Signatur wäre alsoBruno hat geschrieben:Ich möchte aus einer ASCII Date Werte lesen, wobei die Werte in Spalten ausgerichtet sind, d.h. der Wert steht z.B. in sen Spalten 1-8 oder 9-32 usw.
Da ich nicht davon ausgehen kann, daß alle Werte weniger als 8 Stellen haben oder alle Werte rechtsbündig stehen, komme ich mit strtok nicht weiter, da es sein kann, daß zwischen zwei Werten kein Leerzeichen vorkommt.
Was ich gerne programmieren würde, wäre eine Funktionread_int_from_line (s.u.), der ich die Zeile und die Spalten, aus denen ich die Werte lesen will (von - bis) gebe und den dort gelesenen Wert zurückbekomme:
wert_1=read_int_from_line( zeile, von_spalte, bis_spalte);}
Kann mir da jemand einen Tip geben wie man das am schlauesten macht?
int read_int_from_line( char * zeile, unsigned int von_spalte, unsigned int bis_spalte );
An Deiner Stelle würde ich mir das Zeichen an zeile[ bis_spalte ] merken und dann mit einem Nullbyte überschreiben. Anschließend hast Du einen C-String, denn Du mit der Funktion atoi parsen kannst. Nach dem Parsen setzt Du das gemerkte Zeichen wieder zurück an seine Stelle. Damit hast Du Zeile nicht verändert und konntest Deine Zahl sauber auslesen.
Das ist ein recht merkwürdiges Format, das Du da hast, wie kommt's?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
- cloidnerux
- Moderator
- Beiträge: 3125
- Registriert: Fr Sep 26, 2008 4:37 pm
- Wohnort: Ram (Gibts wirklich)
Re: parsen von ASCII Dateien
Willkommen im Forum
Deine Datei sieht mir stark nach einer CSV Datei aus. Hast du sie selber generiert?
Soweit ich weiß, ist es Üblich die einzelnen Spalten über ein Trennzeichen zu Trennen.
Ansonsten könntest du doch auch immer 8 stellen lesen, alles Unnötige entfernen und dann die zahl auslesen, wenn ich deine Beschreibung der Datei richtig verstanden habe.
MfG cloidnerux.
Deine Datei sieht mir stark nach einer CSV Datei aus. Hast du sie selber generiert?
Soweit ich weiß, ist es Üblich die einzelnen Spalten über ein Trennzeichen zu Trennen.
Ansonsten könntest du doch auch immer 8 stellen lesen, alles Unnötige entfernen und dann die zahl auslesen, wenn ich deine Beschreibung der Datei richtig verstanden habe.
MfG cloidnerux.
Redundanz macht wiederholen unnötig.
quod erat expectandum
quod erat expectandum
Re: parsen von ASCII Dateien
Hallo!cloidnerux hat geschrieben:Willkommen im Forum
Deine Datei sieht mir stark nach einer CSV Datei aus. Hast du sie selber generiert?
Soweit ich weiß, ist es Üblich die einzelnen Spalten über ein Trennzeichen zu Trennen.
Ansonsten könntest du doch auch immer 8 stellen lesen, alles Unnötige entfernen und dann die zahl auslesen, wenn ich deine Beschreibung der Datei richtig verstanden habe.
MfG cloidnerux.
Leider keine CSV-Datei und generiert wird die Datei von verschiedenen Programmen, die den FEM Code NASTRAN rausschreiben.
Leider hat jeder Programmhersteller seine eigene Philosophie wie er mit dem 8-Spaltenformat, was NASTRAN verlangt umgeht.
Und spätenstens, wenn ich 8stellige IDs für Knoten oder Element vergeben muß bin ich mit strtok am Ende der Weisheit.
Ciao
Jürgen
"21" ist nur die halbe Wahrheit...
- cloidnerux
- Moderator
- Beiträge: 3125
- Registriert: Fr Sep 26, 2008 4:37 pm
- Wohnort: Ram (Gibts wirklich)
Re: parsen von ASCII Dateien
Also etwas exotischeres, musste erstmal googlen was das ist^^Leider keine CSV-Datei und generiert wird die Datei von verschiedenen Programmen, die den FEM Code NASTRAN rausschreiben
Also legt NASTRAN fest, wie die Datei aufgebaut sein soll und NASTRAN muss es ja auch Interpretieren können.Leider hat jeder Programmhersteller seine eigene Philosophie wie er mit dem 8-Spaltenformat, was NASTRAN verlangt umgeht.
Soweit ich dich jetzt verstanden habe, gibt es 8 Spalten zu 8 Zeichen?
Wieso nimmst du nicht was anderes als strtok, bzw Programmierst dir was eigenes?Und spätenstens, wenn ich 8stellige IDs für Knoten oder Element vergeben muß bin ich mit strtok am Ende der Weisheit.
Hast du dir mal die anderen string-Funktionen angeschaut und/oder das Prinzip hinter C-Strings verstanden?
Redundanz macht wiederholen unnötig.
quod erat expectandum
quod erat expectandum
- fat-lobyte
- Beiträge: 1398
- Registriert: Sa Jul 05, 2008 12:23 pm
- Wohnort: ::1
- Kontaktdaten:
Re: parsen von ASCII Dateien
Xin hat geschrieben:An Deiner Stelle würde ich mir das Zeichen an zeile[ bis_spalte ] merken und dann mit einem Nullbyte überschreiben. Anschließend hast Du einen C-String, denn Du mit der Funktion atoi parsen kannst. Nach dem Parsen setzt Du das gemerkte Zeichen wieder zurück an seine Stelle. Damit hast Du Zeile nicht verändert und konntest Deine Zahl sauber auslesen.
cloidnerux hat geschrieben:Ansonsten könntest du doch auch immer 8 stellen lesen, alles Unnötige entfernen und dann die zahl auslesen, wenn ich deine Beschreibung der Datei richtig verstanden habe.
Ein paar vorschläge hast du ja schon.Bruno hat geschrieben:Und spätenstens, wenn ich 8stellige IDs für Knoten oder Element vergeben muß bin ich mit strtok am Ende der Weisheit.
Hier noch einer von mir:
Leg dir ein 9 Byte array an, setz das 9. byte auf '\0'. Lies mit fread() immer 8 bytes ein, und parse deinen string mit atoi(). Sollte fread() einmal weniger als 8 Zeichen lesen weißt, du, dass du am Ende der Datei bist.
Wenn es vorkommt dass die Felder kürzer sind (z.B. am Ende der Zeile) musst dir noch was überlegen, aber ich bin mir sicher das schaffst du

Haters gonna hate, potatoes gonna potate.
Re: parsen von ASCII Dateien
Hallo!
Habe fread mal im I-net gesucht und folgendes gefunden:
Angeblich werden damit 10 Blöcke a 1*sizeof(int) aus der Datei wert.dat gelesen.
Mit der Datei wert.dat mit dem Inhalt "12345678901234567890" bekomme ich den Output:
Was mich nicht wirklich glücklich macht...
Ich durchschaue aber nicht wo der Fehler liegt.
Edit by Xin: Code-Flags hinzugefügt.
Habe fread mal im I-net gesucht und folgendes gefunden:
Angeblich werden damit 10 Blöcke a 1*sizeof(int) aus der Datei wert.dat gelesen.
Code: Alles auswählen
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int Buffer[10];
FILE *Datei;
int i;
Datei = fopen("wert.dat", "r+b");
if(Datei != NULL)
{
fread(&Buffer, 1*sizeof(int), 10, Datei);
}
for(i = 0; i < 10; i++)
{
printf("Wert %d = %d\n", i, Buffer[i]);
}
return EXIT_SUCCESS;
}
Code: Alles auswählen
Wert 0 = 875770417
Wert 1 = 943142453
Wert 2 = 842084409
Wert 3 = 909456435
Wert 4 = 809056311
Wert 5 = 10
Wert 6 = 4195809
Wert 7 = 0
Wert 8 = 0
Wert 9 = 0
Ich durchschaue aber nicht wo der Fehler liegt.
Edit by Xin: Code-Flags hinzugefügt.
"21" ist nur die halbe Wahrheit...
- fat-lobyte
- Beiträge: 1398
- Registriert: Sa Jul 05, 2008 12:23 pm
- Wohnort: ::1
- Kontaktdaten:
Re: parsen von ASCII Dateien
Ich will dir ja den spaß nicht verderben, deswegen nur ein paar wenige Tips:
Kuck dir mal gaaannnzz genau an WAS du ausliest, wie groß das ist, wieviel du davon du ausliest und welches format das hat.
Dann Überleg dir was du auslesen willst, und wie es kodiert ist (ein blick in den Titel des Threads könnte helfen
), und wie du daraus das machst was du willst.
Kuck dir mal gaaannnzz genau an WAS du ausliest, wie groß das ist, wieviel du davon du ausliest und welches format das hat.
Dann Überleg dir was du auslesen willst, und wie es kodiert ist (ein blick in den Titel des Threads könnte helfen

Haters gonna hate, potatoes gonna potate.
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: parsen von ASCII Dateien
Das könnte ausführlicher werden. ^^
Also... erstens enthält die wert.dat keine ints, sondern eine Ansammlung von ASCII-Zeichen (char), die zufälligerweise Ziffern sind. Damit kann ein Computer eigentlich nichts anfangen, ASCII-Werte sind nur eine Konvention, wie Zahlen (das womit Computer etwas anfangen können) als Text dargestellt werden können (womit wir dann etwas anfangen können.)
Für den Computer ist die ASCII-Wert '0' der Integer-Wert 48, '1' ist 49 usw.
Ein char ist 1 Byte groß, ein int ist vier Byte groß.
Wenn Du nun vier Byte (je ein chars) hintereinander klemmst (also ein int), dann bekommst Du eine Zahl zwischen -2'000'000'000 und +2'000'000'000 raus, während als Text gerade mal vier Ziffern reinpassen. Beides ist 4 Byte groß, aber der Computer betrachtet diese Daten eben vollkommen anders - sie haben ja auch unterschiedliche Typen.
Du musst nicht 10 ints einlesen, sondern 10 chars (also ASCII-Zeichen), um "1234567890" in einem Buffer unterzubringen. Der Buffer sollte dann vom Typ 'char' sein:
Du brauchst 11 chars, damit Du hinten ein Nullbyte anfügen kannst:
10, weil der Index bei 0 beginnt und 10 somit das 11. Char ist.
Dann liest Du mit fread 10 Zeichen ein:
Wenn das geklappt hat, kommen wir wieder zu meinem ersten Posting: Du kannst nun den Buffer an die Funktion atoi (sprechbar "AsciiToInteger") packen.
Jetzt hast Du die erste Zahl gelesen und als als Typ "Integer" vorliegen, die Du mit printf und %d dann ausgeben kannst:
In der Variable "wert" hast Du jetzt die gewünschte Zahl, so dass die Maschine etwas damit anfangen kann und Du damit Deine Berechnungen durchführen kannst.
Also... erstens enthält die wert.dat keine ints, sondern eine Ansammlung von ASCII-Zeichen (char), die zufälligerweise Ziffern sind. Damit kann ein Computer eigentlich nichts anfangen, ASCII-Werte sind nur eine Konvention, wie Zahlen (das womit Computer etwas anfangen können) als Text dargestellt werden können (womit wir dann etwas anfangen können.)
Für den Computer ist die ASCII-Wert '0' der Integer-Wert 48, '1' ist 49 usw.
Ein char ist 1 Byte groß, ein int ist vier Byte groß.
Wenn Du nun vier Byte (je ein chars) hintereinander klemmst (also ein int), dann bekommst Du eine Zahl zwischen -2'000'000'000 und +2'000'000'000 raus, während als Text gerade mal vier Ziffern reinpassen. Beides ist 4 Byte groß, aber der Computer betrachtet diese Daten eben vollkommen anders - sie haben ja auch unterschiedliche Typen.
Du musst nicht 10 ints einlesen, sondern 10 chars (also ASCII-Zeichen), um "1234567890" in einem Buffer unterzubringen. Der Buffer sollte dann vom Typ 'char' sein:
Code: Alles auswählen
char Buffer[11];
Code: Alles auswählen
Buffer[10] = '\0';
Dann liest Du mit fread 10 Zeichen ein:
Code: Alles auswählen
fread(&Buffer, sizeof(char), 10, Datei);
Code: Alles auswählen
int wert = atoi( Buffer );
Code: Alles auswählen
printf( "Wert als String: %s\n", Buffer );
printf( "Wert as Integer: %d\n", wert );
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Re: parsen von ASCII Dateien
Hallo!
Danke fürs auführliche Posting!
Mann ist das kompliziert...
Ich denke immer noch in Fortran, da sind Strings ein eigener Datentyp und der Umgang damit ist recht simpel
Naja, 12 jahre Fortran gegen 6 Wochen C... ist klar, wer da verliert
))
Ciao
Jürgen
Danke fürs auführliche Posting!
Mann ist das kompliziert...
Ich denke immer noch in Fortran, da sind Strings ein eigener Datentyp und der Umgang damit ist recht simpel
Naja, 12 jahre Fortran gegen 6 Wochen C... ist klar, wer da verliert

Ciao
Jürgen
"21" ist nur die halbe Wahrheit...