strukturierte Daten schreiben



  • Hallo,
    wie müsste ich die Zeile:
    ofs << kunde.nummer << " " << kunde.name << " " << kunde.address1 << " " << kunde.address2 << " " << kunde.limit << " " << kunde.schuld << endl;
    ändern um die Daten-Struktur "kunde" mit z.B. "Kund kunde" zu speichern ?

    #include <string>
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    struct Kund
    {
    public:
    	int nummer = 4711;
    	string name = "Juergen";
    	string address1 = "Address_1";
    	string address2 = "Address_2";
    	int limit = 1000;
    	float schuld = 100.0;
    
    };
    
    struct Kund kunde;
    
    void data_write(string const& filename)
    {
    	Kund kunde;
    	ofstream ofs(filename);
    	if (!ofs.bad())
    	{
    		ofs << kunde.nummer << " " << kunde.name << " " << kunde.address1 << " " << kunde.address2 << " " << kunde.limit << " " << kunde.schuld << endl;
    		ofs.close();
    	}
    }
    
    void data_read(string const& filename)
    {
    	ifstream ifs;
    	ifs.open(filename);
    	string gelesen;
    	while (getline(ifs, gelesen))
    	{
    		cout << gelesen << endl;
    	}
    	ifs.close();
    }
    
    int main()
    {
    	string const filename = "kunde";
    	data_write(filename);
    	data_read(filename);
    	cout << "Eingabe erwartet";
    	cin.get();
    }
    

    MfG
    Juergen B.



  • So ich habe den Code umgeschrieben, weil so wie er dasteht ergibt er wenig Sinn. Die Default Initialisierung der Datenstruktur (die sollte man Kunde nennen und nicht Kund) sollte einen sinnvollen Grundzustand festlegen. Dann verwenden wir hier C++ und kein C – struct Kund kunde ergibt somit keinerlei Sinn. Also als erstes ein sinnvoller Konstruktur für Kunde definieren, mit dem man einem Objekt vom Typ Kunden sinnvoll Werte zuweisen kann. Den Spezialfall kann man dann über diesen Konstruktor die Werte zuweisen. Dazu kommt, dass C++ den Default Konstruktor nicht definiert, wenn man einen eigenen Konstruktor definiert. Daher brauchen wir eine explizite Definition des Default Konstruktors. Dieser legt die Werte für die Member so fest, dass er deren Default Initialisierung genutzt wird. D.h. std::string legt leere Strings an, und die Zahlenwerte sind allesamt 0. Das Schreiben eines Objekts von Typ Kunden realisieren wir über einen operator<< analog dazu operator>> kann man das Einlesen umsetzen.

    Ergänzung:
    Mit dem operator<< kann auf beliebige Ausgabekanäle (die von ostream abgeleitet sind) den Datensatz schreiben.

    #include <string>
    #include <iostream>
    #include <ostream>
    #include <fstream>
    
    struct Kunde {
        std::string name_;
        std::string address1_;
        std::string address2_;
        float schuld_;
        int nummer_;
        int limit_;
    
        Kunde() = default;
        Kunde(std::string name, std::string address1, std::string address2, float schuld, int nummer, int limit) :
          name_(name), address1_(address1), address2_(address2), schuld_(schuld), nummer_(nummer), limit_(limit)
        {}
    
    };
    
    std::ostream&
    operator<<(std::ostream& o, Kunde& k) {
        o << k.nummer_ << ",'" << k.name_ << "','" << k.address1_ << "','" << k.address2_ << "'," << k.limit_ << "," << k.schuld_ << "\n";
    
        return o;
    }
    
    int main() {
        Kunde kunde("Juergen", "Address_1", "Address_2", 100.0, 4711, 1000);
        const std::string filename = "kunde.csv";
    
        std::ofstream ofs(filename);
    
        ofs << kunde;
    }
    
    


  • Hallo,

    vielen Dank für Deinen ausführlichen Beitrag und das geänderte Beispiel.
    Dazu hätte ich noch eine Frage zur "structur": müsste das nicht bei C++ "class" heissen ?.

    MfG

    Juergen B.



  • @jbaben sagte in strukturierte Daten schreiben:

    Dazu hätte ich noch eine Frage zur "structur": müsste das nicht bei C++ "class" heissen ?.

    struct und class unterscheiden sich in C++ nur darin, dass in einer struct per Default alle Member public sind und in einer class alle Member per Default private sind.



  • Hallo,

    wie kann ich bei dem gezeigten Programm-Code non "john 0" Daten an die vorhandene Datei anfügen ?

    MfG

    Juergen B.



  • Hallo,

    ich habe es schon gefunden, mit:
    std::ofstream ofs(filename, std::ios_base::out | std::ios_base::app);

    MfG

    Juergen B.



  • @john-0 sagte in strukturierte Daten schreiben:

    Kunde(std::string name, std::string address1, std::string address2, float schuld, int nummer, int limit) :
    name_(name), address1_(address1), address2_(address2), schuld_(schuld), nummer_(nummer), limit_(limit)
    {}

    Warst du nicht der, der immer alle Parameter const haben wollte? Und ausgerechnet bei strings nimmst du keine const-ref? Wolltest du move'n?



  • @john-0
    Ich habe noch das Problem beim lesen und anzeigen der gespeicherten Textdatei "kunde.cvs".
    Mit dem Programm-Code:

    ifs2.open(filename_kunde, std::ios::in);
    while (ifs2 >> kunde.nummer_   >> kunde.name_  >> kunde.address1_  >> kunde.address2_  >> kunde.limit_  >> kunde.schuld_)
    {
                   std::cout << "Kunden-Nummer     = " << kunde.nummer_ << std::endl;
    		std::cout << "Kunden-Name         = " << kunde.name_ << std::endl;
    		std::cout << "Kunden-Adresse1   = " << kunde.address1_ << std::endl;
    		std::cout << "Kunden-Adresse2   = " << kunde.address2_ << std::endl;
    		std::cout << "Kunden-Limmit       = " << kunde.limit_ << std::endl;
    		std::cout << "Kunden-Schuld       = " << kunde.schuld_ << std::endl;
    }
    ifs2.close();
    

    erhalte ich keine Anzeige.
    Ich denke mal das liegt an dem Trennungszeichen ','.
    Ohne Trennungszeichen funktioniert die Anzeige (allerdings nur ohne Leerzeichen zwischen den Eingaben: z.B Adresse1 = "addresse1" und nicht: "addresse1 xy").
    Wie kann ich die Textdatei "kunde.cvs" auslesen ?

    MfG

    Juergen B.



  • Verrätst du uns auch noch, was die Probleme sind? Was erwartest du, was ist die Ausgabe?


  • Mod

    Glaskugel sagt:

     o << k.nummer_ << ",'" << k.name_ << "','" << k.address1_ << "','" << k.address2_ << "'," << k.limit_ << "," << k.schuld_ << "\n";
    

    vs.

    ifs2 >> kunde.nummer_   >> kunde.name_  >> kunde.address1_  >> kunde.address2_  >> kunde.limit_  >> kunde.schuld_
    

    Die beiden sind nicht Gegenteile voneinander.

    edit: Fragesteller hat inzwischen eine Problembeschreibung zugefügt, die Glaskugel hatte also Recht.



  • @DocShoe
    Sorry, ich hatte beim erstellen eine falsche Taste (backspace) gedrückt --> unfertiger Beitrag wurde angezeigt.

    MfG

    Juergen B.



  • @jbaben: Du kannst mittels getline(ifs2, kunde.name_, ',') den Text bis zum Komma einlesen.

    Am besten implementierst du dann den operator >> dafür und liest dann einfach per while (ifs2 >> kunde).



  • @Th69
    So wie ich das verstehe:

    std::fstream ifs2;
    ifs2.open("kunde.cvs, std::ios::in);
    while(ifs2)      // mit "while(ifs2 >> kunde) --> keine Anzeige
    {
                   //get?(ifs2, kunde.nummer_ , ',');        // da fehlt mir im Moment der Befehl um Integer zu lesen
    		getline(ifs2, kunde.name_ , ',');
    		getline(ifs2, kunde.address1_ , ',');
    		getline(ifs2, kunde.address2_ , ',');
                   //get?(ifs2, kunde.limit_ , ',');               // da fehlt mir im Moment der Befehl um Integer zu lesen
    		//get?(ifs2, kunde.schuld_);          // da fehlt mir im Moment der Befehl um Float zu lesen
    
    		std::cout << "Kunden-Nummer     = " << kunde.nummer_ << std::endl;
    		std::cout << "Kunden-Name       = " << kunde.name_ << std::endl;
    		std::cout << "Kunden-Adresse1   = " << kunde.address1_ << std::endl;
    		std::cout << "Kunden-Adresse2   = " << kunde.address2_ << std::endl;
    		std::cout << "Kunden-Limmit     = " << kunde.limit_ << std::endl;
    		std::cout << "Kunden-Schuld     = " << kunde.schuld_ << std::endl;
    	}
    	ifs2.close();
    

    funktioniert das einlesen und anzeigen nicht.



  • Hallo,

    so funktioniert das einlesen und anzeigen der Textdatei "kunde.cvs":

    std::string number = "", limit = "", schuld = "";
    ifs2.open(filename_kunde, std::ios::in);
    while(ifs2)
    	{
    		getline(ifs2, number, ',');
    		getline(ifs2, kunde.name_, ',');
    		getline(ifs2, kunde.address1_, ',');
    		getline(ifs2, kunde.address2_, ',');
    		getline(ifs2, limit, ',');
    		getline(ifs2, schuld);
    
    		// hier fehlt noch die Konvertierung "String to Integer"
                    //kunde.nummer_ = ?(number);
                    //kunde.limit_ = ?(limit);
                    //kunde.schuld_ = ?(schuld);
    
    		std::cout << "Kunden-Nummer     = " << number << std::endl;
    		std::cout << "Kunden-Name       = " << kunde.name_ << std::endl;
    		std::cout << "Kunden-Adresse1   = " << kunde.address1_ << std::endl;
    		std::cout << "Kunden-Adresse2   = " << kunde.address2_ << std::endl;
    		std::cout << "Kunden-Limmit     = " << limit << std::endl;
    		std::cout << "Kunden-Schuld     = " << schuld << std::endl;
    	}
    	ifs2.close();
    

    MfG

    Juergen B.



  • @Jockelx sagte in strukturierte Daten schreiben:

    Warst du nicht der, der immer alle Parameter const haben wollte?

    Da es es ein Beispiel fürs Forum ist, habe ich es deshalb weggelassen.


  • Mod

    @john-0 sagte in strukturierte Daten schreiben:

    @Jockelx sagte in strukturierte Daten schreiben:

    Warst du nicht der, der immer alle Parameter const haben wollte?

    Da es es ein Beispiel fürs Forum ist, habe ich es deshalb weggelassen.

    Hast Du das move(), von dem @Jockelx im nicht zitierten Teil sprach, auch weggelassen, um die Neulinge hier nicht zu verwirren? 🤨


Anmelden zum Antworten