Datei auslesen



  • Hallo zusammen!
    Bin Anfängerin in C und habe eine Frage zur Lösung einer Aufgabe.
    Ich habe eine Textdatei, die Informationen von Songs dieser Form enthält:

    Dateiname|Titel|Interpret|Tracknummer|Album

    Die Datei soll ausgelesen werden, und in dieser Form dann ausgegeben werden:

    Dateiname: .....
    Titel: ....
    Interpret: ......
    Album: ......
    Track: .......

    Ein wages Grundgerüst hätte ich schon:

    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    main()
    {
    
        ifstream fin;     
    
        fin.open("titelliste.txt");  
    
        if (!fin)              
            cerr << "Datei kann nicht geoeffnet werden!\n";
        else {
            while () 
    
            cout << "Dateiname: " <<  << endl;
        }
    
        fin.close();        
    }
    

    Leider habe ich weder ein Beispiel, noch irgendwelche Texte gefunden, mit die mir erklärt hätten, welche Befehle ich nun brauche, um die Aufgabe zu lösen.
    Wäre wahrscheinlich zu dreist zu bitten, dieses Programm zu vervollständigen.
    Durchs Googeln hab ich leider keine passenden Seiten gefunden, welche die Funktionen von fstream so erläutert hätten, dass ich es für die Lösung dieses Problemes hätte anwenden können. Also falls hier jemand passende Beispielprogramme kennt, oder andere Seiten die ich beim Googeln nicht gefunden habe, dannlasst es mich wissen. 😉



  • Hallo,
    Möchtest du bei deinem Problem etwas lernen? Wenn ja, dann folgender Lösungsansatz:

    - Schau dir die Klasse std::string und deren Methoden an. (Insbesondere die find-Methoden).
    - Jetzt öffnest du die gewünschte Datei und suchst immer nach den |-Zeichen. Den Inhalt zwischen diesen Zeichen speicherst du nun in einer gewünschten Variable. (Achtung: Anfang und Ende der Zeile benötigen eine gesonderte Behandlung).
    - Falls du jetzt richtig Gefallen an der Sache gefunden hast, schreibst du dir direkt eine Klasse, die du cvs_reader o.ä. nennst und kapselst die gesammte Funktionalität darin. :).

    Falls du bei deinem Problem nichts lernen willst, musst du es nur sagen und ich klatsche dir den fertigen Code hin... (nicht böse gemeint).

    Gruß Caipi



  • Caipi schrieb:

    [...] eine Klasse, die du cvs_reader o.ä. nennst [...]

    Wohl eher csv_reader, oder? 😉
    *SCNR*



  • Gut, ich gebe auf. Programmieren scheint nun wirklich nicht mein Ding zu sein.
    Die Erklärungen, die ich finde, sind einfach zu hoch für mich, und nicht annähernd so tiefgehend, wie ich es benötigte, um daraus schlau zu werden.
    Ich gebe auf, ich resigniere.
    Sollte jemand das Programm fertig schreiben könne, bitte ich darum.
    Die Aufgaben sind freiwillig, und ich kann mich so auch nicht mit fremden Federn schmücken.
    Vielleicht verstehe ich ja wenigstens das fertige Programm. 😞



  • Hehe nich gleich aufgeben. Geht mir genau so 😉

    Also hier mal ein paar Grundlegende Sachen, ich hoffe die helfen dir:

    int a = 100; // Beispielvariable
    
    ofstream Output ("Test.txt"); // Lege die Datei "Test.txt" an
    Output.write ((char*) &a, sizeof (a)); // Speichere den Wert von a ab 
    Output.close (); // Stream schließen
    
    a = 0 // Erzwingen das a = 0 ist
    
    ifstream Input ("Test.txt"); // Öffne die Datei "Test.txt"
    Input.read ((char*) &a, sizeof(a)); // Lies den Wert von a und weise ihn der Variable zu
    Input.close (); // Stream schließen
    
    cout << a << endl; // Beweis das a wieder = 100 ist!
    

    Das ist erstmal grundlegend wie man mit Dateien arbeiten kann!

    if (Input == NULL)
    {
    		std::cout << "Fehler beim oeffnen von " << Dateiname << "\a" << std::endl; // \a ist ein Piepton, std:: nur schreiben wenn du using namespace std nicht verwendest!
    		std::cout << "Program abort!" << std::endl;
    }
    

    Das ist dann die Ausgabe eines Fehlers. Das passiert zB dann, wenn die Datei schreibgeschützt ist! Auch nur ganz grundlegend erklärt 🙂

    Wenn du jetzt noch den Dateinamen mit angeben möchtest/musst kannst du das zB so machen:

    char buffer[50]; // Dateiname in String
    
    sprintf (buffer, "Test.txt"); // Zuweisung des Dateinamens
    ifstream Input (buffer); // Öffne die Datei "Test.txt"
    cout << buffer; // Dateiname nennen
    

    Desweiteren kann ich dir sagen dass das | eine Art Verknüpfung ist. Wie du deine vorliegenden Daten jetzt in den Code einbringst über fstream weiß ich leider nicht. Da musst du jemand anderes fragen oder MSDN, HILFE etc. befragen.



  • Danke DarkRage.
    Du hast mir einen Ansatz geliefert, von dem aus ich weiterlernen kann.
    mal sehen, wie weit ich komme 😉



  • Kein Problem. Wenn noch was unklar ist dann immer fragen 😉

    Wenn du die Aufgabe gelöst hast würde ich übrigens auch gerne wissen wie, interessiert mich nämlich wie man den Klartext aus deiner Datei in Variablen übergeben kann. Über fstream kann man - soweit ich es gesehen habe - nur Binär speichern, was ja nicht in deinem Sinne ist. Vielleicht gibt es ja doch eine Möglichkeit?!



  • DarkRage schrieb:

    ... interessiert mich nämlich wie man den Klartext aus deiner Datei in Variablen übergeben kann. Über fstream kann man - soweit ich es gesehen habe - nur Binär speichern, was ja nicht in deinem Sinne ist. Vielleicht gibt es ja doch eine Möglichkeit?!

    genau anders herum: mit fstream kann man normalerweiese nur ASCII lesen und schreiben und der Einsatz von read und write

    DarkRage schrieb:

    int a = 100; // Beispielvariable
    
    ofstream Output ("Test.txt"); // Lege die Datei "Test.txt" an
    Output.write ((char*) &a, sizeof (a)); // Speichere den Wert von a ab
    

    .. ist im Grunde die Ausnahme!
    Alles was mit cout und cin geht, geht exakt in der gleichen Weise mit ofstream und ifstream, die ja von ostream und istream abgeleitet sind.

    Also z.B.:

    int a = 9;
       double d = 3.14;
       std::complex< doubel > c( 3, -2.4 );
       ofstream file("ausgabe.txt");
       file << "int: " << a << " double: " << d << "complex: " << c << endl;
       // genau wie:
       cout  << "int: " << a << " double: " << d << "complex: " << c << endl;
    

    @DarkRage: wieso weißt Du, dass die Klasse fstream eine write-Methode hat, aber nicht, dass sie die Streaming-operatoren für alle Basis-Typen besitzt? Wie kommt das?

    Gruß
    Werner



  • Luka_one schrieb:

    Ich habe eine Textdatei, die Informationen von Songs dieser Form enthält:

    Dateiname|Titel|Interpret|Tracknummer|Album

    Die Datei soll ausgelesen werden, und in dieser Form dann ausgegeben werden:

    Dateiname: .....
    Titel: ....
    Interpret: ......
    Album: ......
    Track: .......

    Bau Dir eine Struktur Song

    struct Song
    {
        std::string m_dateiname;
        std::string m_titel;
        // usw.
    

    und die passenden Streaming-Operatoren

    // -- Song lesen
    std::istream& operator>>( std::istream& in, Song& song )
    {
        getline( in, song.m_dateiname, '|' );
        getline( in, song.m_titel, '|' );
        // usw.
        getline( in, song.m_album ); // Ende der Zeile
        return in;
    }
    
    // -- Song schreiben
    std::ostream& operator<<( std::ostream& out, const Song& song )
    {
        cout << "Dateiname: " << song.m_dateiname << std::endl;
        // usw.
        return out;
    }
    

    und dann geht das Einlesen und Ausgaben ohne Zwischenspeichern (!) ganz einfach

    ifstream file("titelliste.txt");
        copy( istream_iterator< Song >( file ), istream_iterator< Song >(),
            ostream_iterator< Song >( cout ) );
    

    Bem.: benötigte Includes: iostream, fstream, iterator, algorithm

    Gruß
    Werner



  • Mit viel Mühe konnte ein Komolitone dieses Programm schreiben, welches sich sehr nahe an der Struktur der uns gegebenen Beispielprogramme hält.

    #include <fstream>
    #include <iostream>
    #include<iomanip>
    
    using namespace std;
    
    main()
    {
    
        char ch;
    	char puffer[100];
    
    	int max=100;
    	char t='|';
    	char s='\n';
    	int i;
    	i=0;
    	int j=0;
    	char* liste[]={"Dateiname: ","Titel: ","Interpret: ","Track: ","Album: "};
    
        ifstream fin;           // Eingabe-Stream erzeugen
    
        fin.open("titelliste.txt");  // Quelldatei oeffnen
    
    	if (!fin)			// Prüfen, ob Datei offen
    		cerr << "Datei kann nicht geöffnet werden!\n";
        else				// Zeichen aus Datei lesen
    
    		while (fin.getline(puffer, max,t))
    
    		{				
    			cout << setw(15)<<left<<liste[j++] <<puffer << endl;		// Zeichen auf Bildschirm ausgebe
    
    			if (j>4)
    			{
    				j=0;
    				cout<<endl;
    			}
    		}
    
        fin.close();            // Quelldatei schliessn
    }
    

    Leider hat dieses Programm noch 2 Haken.
    1. In der gegebenen titelliste.txt steht zum Schluss der Zeile kein weiteres |
    Somit verschiebt sich alles, wenn man getline()benutzt.
    Das Problem behebt sich natürlich, wenn ich in der Datei nochmals | dranhänge, aber ich bin mir ziemlich sicher, dass wir die Textdatei nicht ändern sollen.
    2. sieht die Ausgabe so aus:

    Dateiname: 
    xxxxxx
    Titel: xxxxxxx
    Interpret:xxxxxx
    

    Ich habe keine Ahnung, warum das in der ersten zeile nicht nebeneinander steht.
    Naja, vielleicht seh ich wirklich den Wald vor lauter Bäumen nicht mehr....
    😉



  • Luka_one schrieb:

    Leider hat dieses Programm noch 2 Haken.
    1. In der gegebenen titelliste.txt steht zum Schluss der Zeile kein weiteres |
    Somit verschiebt sich alles, wenn man getline()benutzt.
    Das Problem behebt sich natürlich, wenn ich in der Datei nochmals | dranhänge, aber ich bin mir ziemlich sicher, dass wir die Textdatei nicht ändern sollen.
    2. sieht die Ausgabe so aus:

    Dateiname: 
    xxxxxx
    Titel: xxxxxxx
    Interpret:xxxxxx
    

    Ich habe keine Ahnung, warum das in der ersten zeile nicht nebeneinander steht.
    Naja, vielleicht seh ich wirklich den Wald vor lauter Bäumen nicht mehr....
    😉

    Problem 1 kannst Du beheben, indem Du die Variable t in der Schleife anpasst.

    while (fin.getline(puffer, max,t))
            {       
                cout << setw(15)<<left<<liste[j++] <<puffer << endl;        // Zeichen auf Bildschirm ausgebe
                t = '|';
                if( j == 4 ) t = '\n';
    

    Problem 2 liegt wohl daran, dass Deine Datei vor 'Dateiname' eine leere Zeile enthält und damit einen Zeilenvorschub (LF). Dieser wird mit eingelesen und später bei der Ausgabe erzeugt er dann

    Dateiname: 
    xxxxxx
    

    Einfach vorher alle 'whitespaces' einlesen. Also vor dem Lesen des Dateinamen

    fin >> ws; // whitespaces also auch LF überlesen
    

    Luka_one schrieb:

    Mit viel Mühe konnte ein Komolitone dieses Programm schreiben, welches sich sehr nahe an der Struktur der uns gegebenen Beispielprogramme hält.

    Hmh! ich halte diese 'Struktur' für ziemlich 'anfängermäßig' und C-lastig. Was studiert Ihr den da; und welche Uni ist das?

    Gruß
    Werner



  • Danke Werner!
    Keine Sorge, ich studiere nicht Informatik, sondern E-technik.
    Die Vorlesung heißt 'Grundzüge der Informatik und Programmieren'.
    (Für's 1. Semester)
    Die Vorlesung ist einfach schlecht vorbereitet. Das sieht man auch an der Durchfallquote von 70%. Manche bestehen erst beim 2. oder sogar 3. Anlauf, oder gar nicht, wenn sie komplett aufgeben und den Studiengang wechseln.
    Mehr mag ich dazu auch nicht sagen.


Anmelden zum Antworten