none
Problem mit StreamWriter/StreamReader RRS feed

  • Frage

  • Ich habe in einer Klasse jeweils eine Funktion zum schreiben und eine zum lesen aus einer Textdatei. Hierzu habe ich fopen_s/fprintf/fseek/fscanf_s verwendet. Ich möchte aber nun, um den Speicherpfad der Textdatei im Program eingeben zu können, System::IO:Tongue TiedtreamWriter/StreamReader verwenden. Unten habe ich den entsprechenden Code eingefügt.

    In einer beliebigen Zeile, der Textdatei, stehet als erstes der Name (maximal 20 Zeichen) dann kommen die Zeichen  „x: „ hiernach kommen 20 float Werte danach kommen die Zeichen  „y: „ und zum Schluss noch einmal 20 float Werte. Mit fseek habe ich jedem float Wert 15 Zeichen platz gelassen. Der Vorteil hierbei war das ich jetzt beim auslesen mittels fseek  an die Stelle eines x oder y Wertes gehen konnte und dort mittels fscanf_s (datei, "%f", &y) den kompletten Wert einfach auslesen konnte.

    Mein Problem ist nun das ich es mit StreamWriter/StreamReader nicht hinbekomme. Könnte mir hierbei bitte jemand weiter helfen. Oder falls jemand eine bessere Idee haben sollte wie es einfach zu Lösen ist wäre ich auch hierfür dankbar.

     

     

     

    Quellcodeabschnitt

    using namespace System;

    using namespace System::IO;

     

    class FuzzySet

    {

    private:

    int anzahl_st;

    float st_x[20];

    float st_y[20];

    char Name[20];

     

    public:

     

    void toString(int l_lin, char Name[20])

    /* Schreibt den "l_lin" linguistischen Term in die Datei FuzzyVariable.txt in die "l_lin" Zeile */

    {

    // Müssen auch in getString geändert werden <<<<<<<<

    const int ver = 15; // Anzahl der Stellen in der txt-Datei für ein float Wert

    const int x_ver = 303; // 20 * ver + 3

    const int y_ver = 606; // 40 * ver + 6

    const int Reihen_ver = 628;

    // ver * 40 + 20 + 6 + 2 (+20 für den Namen und +2 für \n)

    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

     

    int stl; // Stelle die geschrieben wird. Beginnt mit 0 in der Datei

    int Reihe = l_lin - 1;

     

    if((File::Exists("FuzzyVariable.txt")) & (l_lin == 1))

    File::Delete("FuzzyVariable.txt");

     

    FILE *datei;

    fopen_s (&datei, "FuzzyVariable.txt", "w");

     

    fseek(datei, (Reihe * Reihen_ver), SEEK_SET);

    fprintf (datei,"x: ");

     

    for(stl = 0; stl <= 19; ++stl) // x-Werte schreiben

    {

    fseek(datei, ((Reihe * Reihen_ver) + (3 + stl*15)), SEEK_SET);

    fprintf (datei,"%f", st_x[stl]);

    }

     

    fseek(datei, ((Reihe * Reihen_ver) + x_ver), SEEK_SET);

    fprintf (datei,"y: ");

     

    for(stl = 0; stl <= 19; ++stl) // y-Werte schreiben

    {

    fseek(datei, ((Reihe * Reihen_ver) + (3 + x_ver + stl*ver)), SEEK_SET);

    fprintf (datei,"%f", st_y[stl]);

     

    if(stl == 19)

    {

    fseek(datei, ((Reihe * Reihen_ver) + y_ver), SEEK_SET);

    fprintf (datei, "%s", Name);

    fseek(datei, ((Reihe * Reihen_ver) + y_ver + 20), SEEK_SET);

    fprintf (datei,"\n");

    }

    }

    fclose (datei);

    };

     

    bool getString(int l_lin)

    /* Methode zum lesen aus der Datei Fuzzy_Menge.txt. Ließt die "l_lin" Zeile aus. Gibt false zurück falls die Datei nicht exestiert oder in der "l_lin" zeile nichts steht.*/

    {

    // Müssen auch in toString geändert werden <<<<<<<<<

    const int ver = 15; // Anzahl der Stellen in der txt-Datei für ein float Wert

    const int x_ver = 303; // 20 * ver + 3

    const int y_ver = 606; // 40 * ver + 6

    const int Reihen_ver = 628;

    // ver * 40 + 20 + 6 + 2 (+20 für den Namen und +2 für \n)

    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

     

    int stl; // Stelle die ausgelesen wird. Beginnt mit 0 in der Datei

    int Reihe = l_lin - 1;

     

    FILE *datei;

    fopen_s (&datei, "Fuzzy_Menge.txt", "r");

     

    if (datei != NULL)

    {

    float x, y;

    char c;

    fseek(datei,(Reihe * Reihen_ver), SEEK_SET);

    if(fscanf_s (datei, "%f", &x) == EOF)

    {

    fclose (datei);

    return false;

    }

    for(stl = 0; stl <= 19; ++stl) // Zum auslesen der x und y Werte

    {

    fseek(datei,((Reihe * Reihen_ver) + 3 + stl*ver), SEEK_SET);

    fscanf_s (datei, "%f", &x);

    fseek(datei, ((Reihe * Reihen_ver) + 3 + x_ver + stl*ver), SEEK_SET);

    fscanf_s (datei, "%f", &y);

    st_x[stl] = x;

    st_y[stl] = y;

    }

    for(int i = 0; i <= 19; ++i) // Zum auslesen des Namens

    {

    fseek(datei, ((Reihe * Reihen_ver) + y_ver + i), SEEK_SET);

    fscanf_s (datei, "%c", &c);

    Name[i] = c;

    }

    fclose (datei);

    }

    else

    return false;

     

    return true;

    };

    };

     

     

    Mittwoch, 5. Dezember 2007 15:24

Antworten

  • Serialisierung von Personendaten

    Person.h

    Quellcodeabschnitt

    #pragma once

     

    using namespace System;

    using namespace System::Runtime::Serialization;

     

    [Serializable]

    public ref class Person

    {

    // Properties

    public: property String^ City;

    public: property String^ FirstName;

    public: property String^ LastName;

    public: property String^ ZipCode;

     

    // Fields

    private: String^ _city;

    private: String^ _firstName;

    private: String^ _lastName;

    private: String^ _zipCode;

    };

     

     

    ConsoleApplicationCPP.cpp

    Quellcodeabschnitt

    // ConsoleApplicationCPP.cpp : main project file.

    #include "stdafx.h"

    #include "Person.h"

     

    using namespace System;

    using namespace System::Diagnostics;

    using namespace System::IO;

    using namespace System::Xml::Serialization;

     

    int main(array ^args)

    {

    Person^ p = gcnew Person();

    p->FirstName = "Daniel";

    p->LastName = "Kuppitz";

    p->ZipCode = "67731";

     

    XmlSerializer^ ser = gcnew XmlSerializer(Person::typeid);

    StreamWriter^ sw = gcnew StreamWriter(File::OpenWrite("output.xml"));

    ser->Serialize(sw, p);

    sw->Close();

     

    Process::Start("output.xml");

     

    return 0;

    }

     

     

    Ausgabe (im IE)

    Quellcodeabschnitt
      <?xml version="1.0" encoding="utf-8" ?>
    - <Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <ZipCode>67731</ZipCode>
        <LastName>Kuppitz</LastName>
        <FirstName>Daniel</FirstName>
      </Person>

     

     

    Das Einlesen gestaltet sich dann genauso einfach, nur dass an Stelle von Serialize die Methode Deserialize aufgerufen wird. Das ganze ist meiner Meinung nach auch für das menschliche Auge gut lesbar.

     

    --

    MfG,

    Daniel Kuppitz

     

    Sonntag, 9. Dezember 2007 14:28

Alle Antworten

  • Wäre es ein Option das ganze als XML zu (de)serialisieren? Wenn sowieso managed Code verwendet werden soll (StreamReader/StreamWriter), dann kann man es auch gleich eleganter machen. Binäre (De)Serialisierung wäre noch eine Option, kommt halt drauf an, ob die Datei außerhalb der Anwendung lesbar sein soll oder nicht.

     

    Ein Beispiel behalt ich mir an der Stelle erstmal vor, würde wohl zu viel Zeit beanspruchen, da meine C++ zu lang vorbei ist .

     

    --

    MfG,

    Daniel Kuppitz

     

    Mittwoch, 5. Dezember 2007 17:17
  • Ich habe noch nie etwas mit XML gemacht. Die Datei soll auch noch außerhalb der Anwendung lesbar sein.

    Für mich wäre in dem fall jetzt die Frage wie aufwendig wäre es sich in XML einzuarbeiten.
    Sonntag, 9. Dezember 2007 13:08
  • Im Prinzip besteht XML nur aus Elementen und Attributen. Wirklich schwer zu verstehen ist es nicht. Zudem machen einem die .NET Komponenten sowohl das Lesen als auch das Schreiben von XML Dateien ziemlich einfach, so das von einigen Regeln, die das XML Format vorgibt, gar nichts wissen muss.

     

    Ich versuch mich mal an einem C++ Beispiel.

     

    --

    MfG,

    Daniel Kuppitz

    Sonntag, 9. Dezember 2007 13:17
  • Serialisierung von Personendaten

    Person.h

    Quellcodeabschnitt

    #pragma once

     

    using namespace System;

    using namespace System::Runtime::Serialization;

     

    [Serializable]

    public ref class Person

    {

    // Properties

    public: property String^ City;

    public: property String^ FirstName;

    public: property String^ LastName;

    public: property String^ ZipCode;

     

    // Fields

    private: String^ _city;

    private: String^ _firstName;

    private: String^ _lastName;

    private: String^ _zipCode;

    };

     

     

    ConsoleApplicationCPP.cpp

    Quellcodeabschnitt

    // ConsoleApplicationCPP.cpp : main project file.

    #include "stdafx.h"

    #include "Person.h"

     

    using namespace System;

    using namespace System::Diagnostics;

    using namespace System::IO;

    using namespace System::Xml::Serialization;

     

    int main(array ^args)

    {

    Person^ p = gcnew Person();

    p->FirstName = "Daniel";

    p->LastName = "Kuppitz";

    p->ZipCode = "67731";

     

    XmlSerializer^ ser = gcnew XmlSerializer(Person::typeid);

    StreamWriter^ sw = gcnew StreamWriter(File::OpenWrite("output.xml"));

    ser->Serialize(sw, p);

    sw->Close();

     

    Process::Start("output.xml");

     

    return 0;

    }

     

     

    Ausgabe (im IE)

    Quellcodeabschnitt
      <?xml version="1.0" encoding="utf-8" ?>
    - <Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <ZipCode>67731</ZipCode>
        <LastName>Kuppitz</LastName>
        <FirstName>Daniel</FirstName>
      </Person>

     

     

    Das Einlesen gestaltet sich dann genauso einfach, nur dass an Stelle von Serialize die Methode Deserialize aufgerufen wird. Das ganze ist meiner Meinung nach auch für das menschliche Auge gut lesbar.

     

    --

    MfG,

    Daniel Kuppitz

     

    Sonntag, 9. Dezember 2007 14:28
  • Es ist wirklich recht leicht.

     

    Dann bedanke ich mich mal und werde XML verwenden.

    Montag, 10. Dezember 2007 14:31