Einfache Textdatei in eine Liste einlesen

Schnelle objektorientierte, kompilierende Programmiersprache.
forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Einfache Textdatei in eine Liste einlesen

Beitrag von forumnewbie » Di Jan 29, 2013 1:36 am

Hallo!

Ich habe mich an diesem Tutorial http://www.proggen.org/doku.php?id=stru ... &s[]=liste orientiert und eine ähnliche Struktur erstellt. Ich habe jetzt eine Liste, die Daten wie Nummer und Name speichert, anzeigt und wieder löscht.
Ich übergebe aber die Daten an meine Liste bzw. Knoten über die Tastatur. Ich möchte aber meine Daten aus einer einfachen "daten.txt" Datei einlesen und an jede Membervariable (Nummer, Name) oder wie in dem Tutorial (Street, Number, ZipCode, Town) zuweisen.
Die Textdatei ist sehr klein und sieht so aus:

Code: Alles auswählen

1234562 Thomas
2034560 Martin
2342345 Mustername
und so weiter.
Ich habe dieses Tutorial gelesen: http://www.proggen.org/doku.php?id=c:tutorial:files (bis "Daten auf die Festplatte schreiben") aber dort steht leider nicht, wie ich die richtigen Felder einer Datei an richtige Variablen zuweisen kann oder ich habe es nicht verstanden.

Die Datei in den Speicher einlesen funktioniert einwandfrei:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
int main() {
    char c;
    FILE *fileP;
    fileP = fopen("daten.txt", "r");

    while(fscanf(fileP, "%c", &c) != EOF) printf("%c", c);
    fclose(fileP);
    return 0;
}
Nur wie verarbeite ich diesen Inhalt richtig bzw. wie weise ich Daten aus den richtigen Feldern (aus der Datei) an die richtigen Membervariablen (Liste) zu?
Könnte mir das bitte jemand an dem Beispiel aus dem Tutorial (Einfach verkettete Listen) zeigen oder mir ein Link geben, wo das mit den Listen gezeigt wird? Ich weiß nicht wie ich das machen kann. :cry:

Vielen Dank!

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von cloidnerux » Di Jan 29, 2013 8:48 am

ch übergebe aber die Daten an meine Liste bzw. Knoten über die Tastatur. Ich möchte aber meine Daten aus einer einfachen "daten.txt" Datei einlesen und an jede Membervariable (Nummer, Name) oder wie in dem Tutorial (Street, Number, ZipCode, Town) zuweisen.
Du musst deine Textdatei "Parsen". Das bedeutet, du liest sie ein und musst deine Informationen aus dem Text herauslösen.
In deinem Fall Weißt du, dass jeder Datensatz in einer Zeile liegt, also durch ein \n oder das EOF abgegrenzt sind.
Du kannst jetzt also deine Komplette Datei in einen String einlesen und mit den Stringfunktionen mit dem \n als Trennzeichen deine einzelnen Zeilen separieren.
Innerhalb deiner Zeile, werden deine Informationen durch ein Leerzeichen getrennt, selbe Funktion, diesmal nur nach " " suchen.
Dann hast du für jede Zeile 2 strings, wobei der eine eine Zahl darstellen soll, also erst Konvertiert werden muss in eine Zahl und einmal einen Namen, der als String bestehen kann.
Wenn du das Iterativ für jede Zeile machst und die geparsten Daten in deine Liste einträgst, bist du schon fertig.

MfG cloidnerux
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von Xin » Di Jan 29, 2013 11:04 am

Ich stimme cloidnerux im Verfahren zu - vor allem, weil Du damit scanf aus der Geschichte entfernst. Benutze fread() dafür.

Du kannst mit isdigit() die Zahlen erkennen. Parsen bedeutet hier, dass Du bei der ersten Zahl Deine Variable auf 0 setzt und für jede Ziffer var = var * 10 + neueZiffer rechnest. Da Du chars als Ziffern bekommst ist '0' nicht 0, sondern 48. Die ziehst Du ab. '1' ist 49 - zieht man '0' ab, erhält man 1, also das, was Du brauchst.

Code: Alles auswählen

int var = 0;
while( isdigit( text[pos] )
{
  char ZifferAlsChar = text[pos];
  char ZifferAlsWert = ZifferAlsChar - '0';  // '0' == 48

  var = var * 10 + ZifferAlsWert;
  pos = pos + 1;    // nächstes Zeichen prüfen.
}
Ähnlich machst Du es mit dem String... sobald der String anfängst, hast Du den Anfang vom String, sobald Du das Zeilenende findest, hast Du das Ende.
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.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von forumnewbie » Di Jan 29, 2013 4:57 pm

Hi danke für eure Antworten!

Bei unseren Aufgaben müssen die Programme noch nicht robust sein. Deshalb genügt mir erstmal fscanf() ( http://www.proggen.org/doku.php?id=c:lib:stdio:fscanf ). Ich habe dieses Tutorial übersehen. Das was ihr beschrieben habt, habe ich verstanden und so ähnlich habe ich mir das vorgestellt, aber das in C umzusetzen ist für mich noch zu schwer. Ich muss mit Strings zunächst mehr Erfahrungen sammeln - ich glaube, dass wir bis jetzt nur eine einzige Aufgabe mit Strings hatten und dort haben wir nur ein String in ein anderes kopieren und seine Länge bestimmt. Wir haben bis jetzt C fast ausschließlich dazu verwendet, um irgendwelche Algorithmen zu implementieren und Mathematikaufgaben zu berechnen. Im nächsten Semester haben wir dann C++ und ich hoffe, dass wir dort lernen werden, wie man robuste Programme schreibt - also wie man die Fehler abfängt und falsche Daten verarbeitet ohne das Programm zum Absturz zu bringen.

Ich werde deshalb zunächst die einfachere Variante mit fscanf() nehmen und hoffe, dass es klappt.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von cloidnerux » Di Jan 29, 2013 5:06 pm

Bei unseren Aufgaben müssen die Programme noch nicht robust sein.
mach dir bitte noch keine Gedanken über Robustheit, solange du noch nicht verstanden hast, warum ein Programm abstürzen kann.
Wir haben bis jetzt C fast ausschließlich dazu verwendet, um irgendwelche Algorithmen zu implementieren und Mathematikaufgaben zu berechnen. Im nächsten Semester haben wir dann C++ und ich hoffe, dass wir dort lernen werden, wie man robuste Programme schreibt - also wie man die Fehler abfängt und falsche Daten verarbeitet ohne das Programm zum Absturz zu bringen.
In C++ wird es sogar etwas schwieriger "robuste" Programme zu schreiben, aber das soll erstmal nicht dein Problem sein.
Zum lernen ist es mitunter sogar hilfreich, wenn dein Programm mal abstürzt oder falsch Funktioniert, weil du dich dann intensiver beschäftigst und dich dann Konstruktiv mit deinem eigenen Code auseinandersetzt. Dabei lernst du dann auch Fehler zu suchen, worauf man zu achten hat und wie man selber Fehler vermeiden kann.
Daher solltest du meiner Meinung nach nicht darauf warten, dass dir in der Uni jemand etwas beibringt, sondern du solltest dich auch selber mit Programmierung und C auseinanader setzten, das wird dir sehr helfen.

MfG cloidnerux
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von Xin » Di Jan 29, 2013 5:29 pm

forumnewbie hat geschrieben:Bei unseren Aufgaben müssen die Programme noch nicht robust sein.
Gut, sollte Dir Dein Prof das so gesagt haben, darfst Du ihm von meiner Seite erklären, dass er ein Idiot ist.

Es ist besser, Du schreibst ein Programm, dass nichts kann, dafür aber auch nichts kaputt macht, als dass Du ein Programm schreibst, was eventuell etwas kann, aber eventuell auch was kaputt macht.

Würdest Du bei mir lernen, wäre ein Programm falsch, wenn Du das richtige Ergebnis erzeugst, aber dafür über einen falschen Weg stolperst.
Ein Programm, dass scanf() enthält ist aus Prinzip falsch.
forumnewbie hat geschrieben:Das was ihr beschrieben habt, habe ich verstanden und so ähnlich habe ich mir das vorgestellt, aber das in C umzusetzen ist für mich noch zu schwer. Ich muss mit Strings zunächst mehr Erfahrungen sammeln - ich glaube, dass wir bis jetzt nur eine einzige Aufgabe mit Strings hatten und dort haben wir nur ein String in ein anderes kopieren und seine Länge bestimmt. Wir haben bis jetzt C fast ausschließlich dazu verwendet, um irgendwelche Algorithmen zu implementieren und Mathematikaufgaben zu berechnen. Im nächsten Semester haben wir dann C++ und ich hoffe, dass wir dort lernen werden, wie man robuste Programme schreibt - also wie man die Fehler abfängt und falsche Daten verarbeitet ohne das Programm zum Absturz zu bringen.
Lass ich mich das abkürzen: Du wirst dort nicht lernen, wie man robuste Programme schreibt, Du wirst doch lernen, wie man größere Programme schreibt.

Wenn Du lernen willst, auf Fehler zu achten, gebe ich Dir den Tipp, es mit kleinen Programmen zu lernen.
Ansonsten erwarte nicht, dass Du in der Ausbildung etwas beigebracht bekommst. Das ist jetzt Dein Job. Je nachdem, wie gut Du Deinen Job machst, wirst Du später bezahlt.
forumnewbie hat geschrieben:Ich werde deshalb zunächst die einfachere Variante mit fscanf() nehmen und hoffe, dass es klappt.
Später wird keiner mehr nach einem "zunächst" fragen. Dein Code geht sofort in die Produktiv-Phase. Wenn er dann den Kunden um die Ohren fliegt, wird man sich fragen, wer das geschrieben hat.
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.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von forumnewbie » Di Jan 29, 2013 5:38 pm

cloidnerux hat geschrieben:
Daher solltest du meiner Meinung nach nicht darauf warten, dass dir in der Uni jemand etwas beibringt, sondern du solltest dich auch selber mit Programmierung und C auseinanader setzten, das wird dir sehr helfen.
Stimme dir absolut zu und das habe ich auch vor. Ich hoffe, dass ich in den Ferien nach den ganzen Prüfungen genug Freizeit haben werde, um dieses Vorhaben zu realisieren.
Im Moment fehlt mir leider die Zeit, um mich mit dieser Sprache intensiver auseinandersetzen zu können (wegen den anderen Fächern).

Ich habe jetzt die ganze Datei einlesen und konnte richtige Werte an die richtigen Variablen zuweisen.

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
int main() {
    char c;
    int i = 0;
    char string[256];
    FILE * fileP = fopen( "daten.txt", "r" );

    if( fileP )
    {
        while(fscanf(fileP, "%c", &c) != EOF)
        {
            fscanf( fileP, "%i", &i );
            fscanf( fileP, "%s", string );

            printf( "String gelesen: %s\n", string );
            printf( "Integer gelesen: %d\n", i );
        }
    }
    fclose(fileP);
    return 0;
}
Ich verstehe jedoch diese Zeile nicht:

Code: Alles auswählen

while(fscanf(fileP, "%c", &c) != EOF)
1. Befindet sich in der Variable EOF der Wert -1, der das Ende einer Datei markiert? Das gibt mir zumindest printf() aus. Wenn ja, wie unterscheidet die Funktion fscanf() diese Variable EOF von der Zahl -1, die in einer Datei steht/stehen kann?
2. Geht diese Schleife jedes einzelne Zeichen der Datei durch und wiederholt die Schleife bei jedem neuen Zeichen? Also wenn die Datei aus 100 Zeichen besteht, dann wird die Schleife 100 Mal wiederholt?
3. Wie erkennen fscanf()-Funktionen in der while-Schleife, dass sie die Werte aus der ersten Zeile, dann aus der zweiten Zeile, dann aus der dritten Zeile einlesen müssen?
Dieses Beispiel funktioniert, aber ich verstehe nicht warum. Könnte mir bitte jemand das erklären?
Danke!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von Xin » Di Jan 29, 2013 5:47 pm

forumnewbie hat geschrieben:Ich verstehe jedoch diese Zeile nicht:

Code: Alles auswählen

while(fscanf(fileP, "%c", &c) != EOF)
1. Befindet sich in der Variable EOF der Wert -1, der das Ende einer Datei markiert? Das gibt mir zumindest printf() aus. Wenn ja, wie unterscheidet die Funktion fscanf() diese Variable EOF von der Zahl -1, die in einer Datei steht/stehen kann?
Die Zahl in der Datei wird nach c geschrieben. Verglichen wird der Rückgabewert von fscanf.
forumnewbie hat geschrieben:2. Geht diese Schleife jedes einzelne Zeichen der Datei durch und wiederholt die Schleife bei jedem neuen Zeichen? Also wenn die Datei aus 100 Zeichen besteht, dann wird die Schleife 100 Mal wiederholt?
Nein, es wird ein Zeichen gelesen. Deswegen glaube ich auch irgendwo nicht, dass Du erfolgreich die Datei gelesen hast - denn ich verstehe den Code auch nicht als die Lösung des von Dir beschriebenen Problems.

Da Du den Code nicht geschrieben hast, solltest Du den Autor mal fragen, wie das funktionieren soll.
forumnewbie hat geschrieben:3. Wie erkennen fscanf()-Funktionen in der while-Schleife, dass sie die Werte aus der ersten Zeile, dann aus der zweiten Zeile, dann aus der dritten Zeile einlesen müssen?
Dieses Beispiel funktioniert, aber ich verstehe nicht warum. Könnte mir bitte jemand das erklären?
Das erkennt fscanf() nicht. Und ich kann Dir auch nicht erklären, warum es funktioniert, denn wenn ich es richtig verstehe, funktioniert es nicht. Wenn es also doch funktioniert, verstehe ich es nicht, also kann ich es Dir nicht erklären.

PS: Selbst wenn es funktionieren sollte - würdest Du mir das als Lösungsvorschlag präsentieren, würde ich es als falsch zurückgeben.

PPS: Als Tipp... schau Dir mal an, ob die Integer-Werte stimmen. Der erste ist vermutlich falsch, der Rest ist Glücksspiel.
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.

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von forumnewbie » Di Jan 29, 2013 5:57 pm

Das Programm liest alle Daten ein, aber:
Wie du geschrieben hast, ist der erste Integer-Wert falsch. Die anderen stimmen. Und der letzte Datensatz wird doppelt ausgegeben. :shock: Also die komplette Datei wird eingelesen, aber mit 2 Fehlern.

Was muss in der While-Schleife stehen, damit es richtig funktioniert - damit Zeile für Zeile eingelesen wird? Bzw. wie muss man das Beispiel aus dem Tutorial erweitern, damit dort nicht nur eine Zeile eingelesen wird?


PS: Hab's hinbekommen:

Code: Alles auswählen

while(fscanf(fileP, "%i", &i) != EOF)
Darf man das so machen? Es funktioniert dieses Mal richtig. Falls das keine gute Lösung ist, könnte mir jemand eine bessere zeigen?

forumnewbie
Beiträge: 80
Registriert: Di Jan 15, 2013 9:02 pm

Re: Einfache Textdatei in eine Liste einlesen

Beitrag von forumnewbie » Di Jan 29, 2013 6:23 pm

Gut, hat sich erledigt. Ich habe jetzt verstanden wie fscanf funktioniert.

Das ist jetzt wahrscheinlich die saubere Lösung:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
int main() {
    int i = 0;
    char string[256];
    FILE * fileP = fopen( "daten.txt", "r" );

    if( fileP )
    {
        while(fscanf(fileP, "%i %s", &i, string) != EOF)
        {
            printf( "String gelesen: %s: ", string );
            printf( "Integer gelesen: %d\n", i );
        }
    }
    fclose(fileP);
    return 0;
}
In der While-Schleife werden Werte aus der Datei Zeile für Zeile an die Variablen übergeben und diese Variablen kann ich dann einfach in der While-Schleife verwenden und ich muss die Datei in der Schleife nicht mehr einlesen.

Antworten