Datensätze aus txt lesen
-
Nabend!
Ich möchte aus einer zuvor erstellten .txt Datei Daten zeilenweise auslesen, bestimmten Variablen in einer Struktur zuordnen und ausgeben. Wie mache ich das am besten?
Beispiel txt Datei:
00001 mustermann bernd 01.01.1980 00002 musterfrau brigitte 02.10.2009
Struktur:
typedef struct gd_e { ui_t gdTag; ui_t gdMonat; ui_t gdJahr; } gd_t; // typedef struct person_e { ui_t identNr; nam_t fNam, vNam; gd_t gebDat; } person_t;
meine idee war mit fscanf bis zu einem leerzeichen einzulesen und entsprechend zu speichern, scheint mir aber sehr aufwändig. kann man das einfacher machen? freue mich über tipps, bin noch c-neuling btw
-
zum zeilenweisen einlesen nimmst am besten "fgets()" dort findest ein paar beispiele;)
http://www.cplusplus.com/reference/clibrary/cstdio/fgets/man kann auch direkt die structs in der datei ablegen, ist aber so ne sache, bzw solltest dann das schreib und lese programm im ideal fall mit dem selben compiler und den gleichen einstellungen compilieren, sonst könnts probleme geben...
oder du machst das gleich richtig und nimmst ne db oder ein daten austausch format z.b. csv,xml,json und alle die mir jetzt auf die schnelle nicht eingefallen sind:)
lg lolo
-
Hallo,
du kannst mit einem fscanf Aufruf alle Elemente einer Struktur aus einer Textdatei einlesen. Ich habe in meinem Beispiel schlichte Variable benutzt, um mir keinen Wolf tippen zu müssen und meine Textdatei hat den folgenden Aufbau:000001 Klara Fall 01.01.1980
000002 Rainer Zufall 10.10.1999Hier der Code:
#include <stdio.h> int main() { char* fname = "test.txt"; FILE* fp = fopen ( fname, "rt" ); char vname[256], nname[256]; int tag, monat, jahr, id, n = 6; // Anzahl der einzulesenden Elemente. if ( fp == NULL ) return 1; while ( n == fscanf ( fp, "%d %s %s %d.%d.%d\n", &id, vname, nname, &tag, &monat, &jahr )) printf ( "%d %s %s %d.%d.%d\n" , id, vname, nname, tag, monat, jahr ); fclose(fp); return 0; }
Gruß,
B.B.
-
hmm ich kriegs einfach net hin. also die txt datei hat folgendes layout:
2 // Anzahl abgespeicherter Datensätze 00001 // und dann halt so wie oben schon beschrieben mustermann bernd 01.01.1980 00002 musterfrau brigitte 02.10.2009
und dann will ich das halt so abspeichern:
fscanf(fp, "%i\n\n", &AnzDat); while (i<AnzDat){ fscanf(fp, "%i\n%s\n%s\n%d.%d.%d\n\n" , &Person[i].identNr , &Person[i].fNam , &Person[i].vNam , &Person[i].gebDat.gdTag , &Person[i].gebDat.gdMonat , &Person[i].gebDat.gdJahr ); i++; }
klappt aber nicht
und wie ich das mit fgets zeilenweise machen könnte ist mir auch nicht so ganz klar...wäre nett wenn mir jmd helfen könnte!
-
Und was genau klappt nicht?
Das geht bei deinem 'Layout' genauso, die Zeilenumbrüche werden als whitespaces erkannt und übersprungen. Die Adressoperatoren vor den char Array Variablen sind überflüssig, eine Arrayvariable ist bereits stellvertredend für ihre Adresse.
Wenn du fgets nimmst, musst du die Zahlen konvertieren, wenn du sie in deiner Struktur speichern willst.
-
Prog stürzte immer ab, aber habs jetzt irgendwie hinbekommen mit fgets.
weiß selbst nicht worans lag, mit trial&error-verfahren hats aber zum glück nach stunden noch geklappt... naja, trotzdem danke für die hilfe!
-
/*****************************************************************************/ /* ReadPerFromFile(): Datensaetze aus einer Textdatei lesen */ /*****************************************************************************/ /* Rueckgabewert: Zeiger auf dyn. Strukturarray */ /* Eingang : Zeiger auf Dateiname (pFileName) */ /* Ausgang : Personendaten in dyn. Strukturarray abgespeichert */ /*****************************************************************************/ pperson_t ReadPerFromFile( const char *pFileName ) { person_t PerArr[PERANZMAX+1]; /* Hilfsfeld fuer Personen */ pperson_t pPerArr; /* Rückgabewert */ int PerAnz, /* Personenanzahl */ iAktP; /* Laufvariable fuer Hilfsfeld */ FILE *fp; /* Dateizeiger festlegen */ char nz[2]; /* Hilfsstring fuer Zeilenwechsel */ fp = fopen( pFileName, "r" ); /* Datei zum lesen oeffnen */ fscanf( fp, "%d", &PerAnz ); /* PerAnz lesen */ for( iAktP = 0; iAktP < PerAnz; iAktP++ ) /* PerAnz Datensaetze lesen */ { /* identNr lesen und Lesezeiger zur naechsten Zeile */ fscanf( fp, "%d", &PerArr[iAktP].identNr ); fgets( nz, 2, fp ); /* Familienname leseDn und '\n' aus Namen entfernen */ fgets( PerArr[iAktP].fNam, NAMLEN, fp ); PerArr[iAktP].fNam[strlen( PerArr[iAktP].fNam )-1] = '\0'; /* Vorname lesen und '\n' aus Namen entfernen */ fgets( PerArr[iAktP].vNam, NAMLEN, fp ); PerArr[iAktP].vNam[strlen( PerArr[iAktP].vNam )-1] = '\0'; /* Geburtsdaten lesen */ fscanf( fp, "%d", &PerArr[iAktP].gebDat.gdTag ); fscanf( fp, "%d", &PerArr[iAktP].gebDat.gdMonat ); fscanf( fp, "%d", &PerArr[iAktP].gebDat.gdJahr ); } fclose( fp ); /* Datenstrom schlieszen */ PerArr[iAktP].fNam[0] = EMPTYTAG_C; /* EndDatensatz markieren($) */ /* Dyn. Strukturarray erstellen und wenn moeglich, Daten reinkopieren */ if( NULL == ( pPerArr = (pperson_t)calloc( iAktP+1, sizeof(person_t) ))) { printf("\n\a Kein Arbeitsspeicher!"); pPerArr = NULL; } else { memcpy( pPerArr, PerArr, (iAktP+1) * sizeof(*pPerArr) ); } return pPerArr; } /* ReadPerFromFile() */
Wenn's nicht schon zu spät is
Gruß
Johann
-
Bei einer vorgegenen ASCCI-Datei (*.txt) sollte man besser die Funktion getline() verwenden!
-
berniebutt schrieb:
Bei einer vorgegenen ASCCI-Datei (*.txt) sollte man besser die Funktion getline() verwenden!
fgets!
-
Johann2 schrieb:
/*****************************************************************************/ /* ReadPerFromFile(): Datensaetze aus einer Textdatei lesen */ /*****************************************************************************/ /* Rueckgabewert: Zeiger auf dyn. Strukturarray */ /* Eingang : Zeiger auf Dateiname (pFileName) */ /* Ausgang : Personendaten in dyn. Strukturarray abgespeichert */ /*****************************************************************************/ pperson_t ReadPerFromFile( const char *pFileName ) { person_t PerArr[PERANZMAX+1]; /* Hilfsfeld fuer Personen */ pperson_t pPerArr; /* Rückgabewert */ int PerAnz, /* Personenanzahl */ iAktP; /* Laufvariable fuer Hilfsfeld */ FILE *fp; /* Dateizeiger festlegen */ char nz[2]; /* Hilfsstring fuer Zeilenwechsel */ fp = fopen( pFileName, "r" ); /* Datei zum lesen oeffnen */ fscanf( fp, "%d", &PerAnz ); /* PerAnz lesen */ for( iAktP = 0; iAktP < PerAnz; iAktP++ ) /* PerAnz Datensaetze lesen */ { /* identNr lesen und Lesezeiger zur naechsten Zeile */ fscanf( fp, "%d", &PerArr[iAktP].identNr ); fgets( nz, 2, fp ); /* Familienname leseDn und '\n' aus Namen entfernen */ fgets( PerArr[iAktP].fNam, NAMLEN, fp ); PerArr[iAktP].fNam[strlen( PerArr[iAktP].fNam )-1] = '\0'; /* Vorname lesen und '\n' aus Namen entfernen */ fgets( PerArr[iAktP].vNam, NAMLEN, fp ); PerArr[iAktP].vNam[strlen( PerArr[iAktP].vNam )-1] = '\0'; /* Geburtsdaten lesen */ fscanf( fp, "%d", &PerArr[iAktP].gebDat.gdTag ); fscanf( fp, "%d", &PerArr[iAktP].gebDat.gdMonat ); fscanf( fp, "%d", &PerArr[iAktP].gebDat.gdJahr ); } fclose( fp ); /* Datenstrom schlieszen */ PerArr[iAktP].fNam[0] = EMPTYTAG_C; /* EndDatensatz markieren($) */ /* Dyn. Strukturarray erstellen und wenn moeglich, Daten reinkopieren */ if( NULL == ( pPerArr = (pperson_t)calloc( iAktP+1, sizeof(person_t) ))) { printf("\n\a Kein Arbeitsspeicher!"); pPerArr = NULL; } else { memcpy( pPerArr, PerArr, (iAktP+1) * sizeof(*pPerArr) ); } return pPerArr; } /* ReadPerFromFile() */
Wenn's nicht schon zu spät is
Gruß
Johanngenau so hab ichs jetzt auch gemacht ^^ wir sind nicht zufällig im selben studiengang, oder? sieht mir doch sehr nach ebels aufgabe aus
-
wir sind nicht zufällig im selben studiengang, oder? sieht mir doch sehr nach ebels aufgabe aus
Jops sind wir. Mein Prog wurde auch schon heute morgen von Hamel geprüft.
Darum auch das:
Wenn's nicht schon zu spät is
xD man hat ich Glück das ich Hamel noch rechtzeitig angetroffen hatte. Bin morgens um 10.00 Uhr hin, hatte es nicht mitgekriegt das mein Abgabetermin auf 8 Uhr vorgestetzt wurde und der hat dann doch noch "nen Auge zu gedrückt"
Gruß
Johann
-
Hi
Ich bin auch beim Ebel und muss morgen abgeben und komme garnicht klar könnte mir einer von euch "Aushelfen"??
LG
-
Calyx12432132 schrieb:
/*****************************************************************************/ /* ReadPerFromFile(): Datensaetze aus einer Textdatei lesen */ /*****************************************************************************/ /* Rueckgabewert: Zeiger auf dyn. Strukturarray */ /* Eingang : Zeiger auf Dateiname (pFileName) */ /* Ausgang : Personendaten in dyn. Strukturarray abgespeichert */ /*****************************************************************************/ pperson_t ReadPerFromFile( const char *pFileName ) { person_t PerArr[PERANZMAX+1]; /* Hilfsfeld fuer Personen */ pperson_t pPerArr; /* Rückgabewert */ return pPerArr; } /* ReadPerFromFile() */
Wie stellst du im aufrufenden Kontext die Anzahl der gelieferten Werte fest?
Wo prüfst du den Rückgabewert der Dateilesefunktionen, d.h. wie reagiert dein Programm, wenn nicht genau deine Struktur mit genau der Anzahl Elemente vorliegt? Richtig! Undefiniertes Verhalten, Note 6, setzen.