Probleme mit Aufgabe



  • Hallo,
    ich habe folgende Aufgabe gestellt bekommen. Habe gerade angefangen mit dem Programmieren und bisher gab es nur relativ leichte Aufgaben. Bei dieser weiß ich nicht so recht was ich zu tuen hab und wie ich das Programm schreiben soll. Mein Skript gibt da auch nicht viel her und im Internet hab ich auch noch nicht brauchbares gefunden. Hoffe ihr könnt mir helfen und die Aufgabe etwas erkären. Ist weniger Text als es aussieht.

    Danke schon mal Christian

    So sieht die Aufgabenstellung aus:

    Gegeben ist eine Datei (in Form einer „Struktur“) mit Daten für eine Liste über Leistungsnachweise.
    Die Datei enthält maximal 100 Datensätze von gleichem Aufbau. Jeder Datensatz ist dabei wie folgt strukturiert:

    Name - maximal 20 Zeichen array of character
    Vorname - maximal 20 Zeichen array of character
    Matrikelnummmer - 6-stellige Zahl long integer
    Adresse - Struktur mit unterschiedlichen Komponenten record
    Postleitzahl - 5-stellige Zahl long integer
    Stadt - maximal 20 Zeichen array of character
    Straße - maximal 20 Zeichen array of character
    Geschlecht - 0 für weiblich, 1 für männlich bool
    Noten - Notenwerte für maximal 10 Fächer array of integer
    Gesucht ist die nach Matrikelnummern sortierte Liste mit allen Personen, die mindestens in einem Fach eine ausreichende Leistung (Note 4 oder besser) erzielt haben und in Darmstadt wohnen.

    Programmentwurf
    1. Als erstes muss die Anzahl der Personen eingegeben ( 0 < Anzahl <=100 ) und einige Datensätze erstellt werden.
    2. Anschließend werden die Daten als Datei abgespeichert.
    3. Danach sollen in einem seperaten Programm alle Daten eingelesen werden.
    4. In diesem Programm werden nun alle Datensätze nach den angegebenen Bedingungen sortiert.und ausgegeben.
    Bei der Ausgabe sollen zuerst die Matrikelnummer, anschließend der Nachname, der Wohnort sowie die Anzahl der bestandenen Fächer ausgegeben werden.
    Ausgabebeispiel:
    456321 Schmidt Darmstadt 5 bestandene Leistungsnachweise
    456478 Mueller Darmstadt 3 bestandene Leistungsnachweise
    573452 Streber Darmstadt 10 bestandene Leistungsnachweise
    598765 Looser Darmstadt 1 bestandener Leistungsnachweis

    Testbeispiel
    Man überlege sich eine bestimmte Anzahl von Datensätzen so, dass einerseits die Eingabe in einer begrenzten Zeit möglich ist und andererseits die Lösung der gestellten Aufgabe nachvollzogen werden kann.
    Hilfe für Übungsblatt 6 :

    in der Variablen anzahl steht die Anzahl der Einträge.
    Als erster Eintrag wird die Anzahl geschrieben, dann kann das Auslese-Programm die richtige Anzahl auslesen.
    Alternativ halten sich beide Programm an eine feste Anzahl, z.B. 100 Einträge.
    Es gibt ein Array von Strukturen dateielement datensatz[100] ,in dem sich die Daten befinden.

    Bisher hab ich nur das geschrieben:

    # include <iostream>
    using namespace std;

    struct Adresse
    {
    long integer Postleitzahl;
    array of character Stadt;
    array of character Straße;
    };

    struct Datensatz
    {
    array of character Name;
    array of character Vorname;
    long integer Martikelnummer;
    bool Geschlecht;
    array of integer Noten;
    };

    Zusätzlich hab ich noch die Hilfe bekommen wie man etwas Schreiben und Lesen kann:

    Schreiben:
    cout << "unter welchem namen speichern ? " << endl;
    cin >> speichername;
    // speichername = "../aufgabe5_04/datensatz"; // oder fester Dateiname
    FILE *stream;
    /* Open for write */
    if( (stream = fopen( speichername, "w+b" )) == NULL )
    {
    cout << "The file was not opened" << endl; //Fehlerbehandlung
    return(-1);
    }
    else
    {
    cout << "The file was opened" << endl; // alles ok
    fwrite ( &anzahl, sizeof(anzahl), 1, stream); // erster Eintrag ist Anzahl
    fwrite ( datensatz, sizeof(datensatz), 1, stream); // jetzt das Array
    /* Close stream */
    if( fclose( stream ) )
    cout << "The file was not closed" << endl;
    else
    cout << "file was closed " << endl;
    }
    Überdenken Sie, warum anzahl per Adressoperator, datensatz direkt als Parameter übergeben werden müssen.

    **Lesen:**if( (stream = fopen( speichername, "rb" )) == NULL )
    // if( (stream = fopen( "../aufgabe5_04/datensatz", "rb" )) == NULL )
    //falls fester Name vereinart
    {
    cout << "The file was not opened" << endl; // falls Fehler
    return(-1);
    }
    else
    {
    cout << "The file was opened" << endl; // alles ok
    fread ( &anzahl, sizeof(anzahl), 1, stream);
    cout << " Anzahl "<< anzahl << endl;
    fread ( datensatz, sizeof(datensatz), 1, stream);



  • mach doch mal das

    1. Als erstes muss die Anzahl der Personen eingegeben ( 0 < Anzahl <=100 ) und einige Datensätze erstellt werden.

    Etwas einlesen wirst du doch können.

    PS: Mit richtigen tags sieht es so aus.

    # include <iostream>
    using namespace std;
    
    struct Adresse
    {
    	long integer Postleitzahl;
    	array of character Stadt;
    	array of character Straße;
    };
    
    struct Datensatz
    {
    	array of character Name;
    	array of character Vorname;
        long integer Martikelnummer;
    	bool Geschlecht;
    	array of integer Noten;
    };
    


  • jetzt seh ichs jetzt auch

    ein array mach man so

    char name[20];
    

    Vielleicht kannst du doch noch nichts einlesen. 😃



  • Danke,
    sorry ich habe wirklich keinen Plan wie die Aufgabe zu lösen ist.
    Das sortieren am Ende und das Ausgeben dürfte kein Problem sein.

    Mein Problem ist es die Datensätze zu erstellen und abzuspeichern.

    ok jetzt sieht es wie folgt aus

    # include <iostream>
    using namespace std;
    
    struct Adresse
    {
    	long integer Postleitzahl;
    	char Stadt[20];
    	char Straße[20];
    };
    
    struct Datensatz
    {
    	char Name[20];
    	char Vorname[20];
        long integer Martikelnummer;
        Adresse adresse;
    	bool Geschlecht;
    	int Noten[10];
    };
    


  • Hallo

    Ich empfehle dir statt mit char-arrays zu arbeiten dich für std::strign zu entscheiden und zweitens solltest du nun mal anfangen den ersten Punkt der Aufgabenstellung zu bearbeiten. Drittens solltest du dich entscheiden, ob du c oder c++ programmieren willst. Was du da machst, ist ein Mix aus beiden und in der Regel ist das nicht unbedingt sinnvoll.

    chrische



  • chrische5 schrieb:

    Ich empfehle dir statt mit char-arrays zu arbeiten dich für std::strign zu entscheiden
    chrische

    Das macht das speichern aber aufwendiger.



  • Hallo

    bedenke schrieb:

    chrische5 schrieb:

    Ich empfehle dir statt mit char-arrays zu arbeiten dich für std::strign zu entscheiden
    chrische

    Das macht das speichern aber aufwendiger.

    Verstehe ich nicht und sehe ich dementsprechend nicht so.

    chrische



  • chrische5 schrieb:

    Hallo

    Ich empfehle dir statt mit char-arrays zu arbeiten dich für std::strign zu entscheiden und zweitens solltest du nun mal anfangen den ersten Punkt der Aufgabenstellung zu bearbeiten. Drittens solltest du dich entscheiden, ob du c oder c++ programmieren willst. Was du da machst, ist ein Mix aus beiden und in der Regel ist das nicht unbedingt sinnvoll.

    chrische

    Ich empfehle dir dem OP nicht Hinweise auf eine falsche Loesung seiner Aufgabe zu geben.



  • chrische5 schrieb:

    Verstehe ich nicht und sehe ich dementsprechend nicht so.
    chrische

    struktur mit char[] speichern
    Pseudocode:
    write(strukt, sizeof(strukt))

    und wie machst du es mit nem std::string?



  • bedenke schrieb:

    chrische5 schrieb:

    Verstehe ich nicht und sehe ich dementsprechend nicht so.
    chrische

    struktur mit char[] speichern
    Pseudocode:
    write(strukt, sizeof(strukt))
    und wie machst du es mit nem std::string?

    file << strukt;
    


  • Konrad Rudolph schrieb:

    file << strukt;
    

    Konnte ich jetzt nicht glauben und hat auch zu dem geführt, was ich dachte.

    #include <string>
    #include <fstream>
    
    struct A {
    	int i;
    	std::string text;
    } strukt;
    
    int main() {
    	std::fstream file("C:\\test123.txt", std::ios::out);
    	strukt.i = 10;
    	strukt.text = "hallo 123";
    	file << strukt;
    }
    

    error C2679: Binärer Operator '<<': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operator vom Typ 'A' akzeptiert (oder keine geeignete Konvertierung möglich)



  • Ja, Du solltest den Operator vielleicht noch geeignet überladen.



  • Konrad Rudolph schrieb:

    Ja, Du solltest den Operator vielleicht noch geeignet überladen.

    bedenke schrieb:

    chrische5 schrieb:

    Ich empfehle dir statt mit char-arrays zu arbeiten dich für std::strign zu entscheiden
    chrische

    Das macht das speichern aber aufwendiger.

    Oder wie machst du das so einfach wie write(strukt, sizeof(strukt)) ?



  • Man könnte ihn auch einfach so speichern:

    struct foo
    {
      int i;
      string str;
    };
    
    foo f;
    f.i = 12;
    f.str = "Hallo Welt";
    
    ofstream file( "foo" );
    file.write( (const char*)&f.i, sizeof( int ) );
    file.write( (const char*)&f.str.size(), sizeof( string::size_type ) );
    file.write( (const char*)f.str.data(), f.str.size() );
    
    //einlesen
    ifstream file( "foo" );
    
    file.read( (char*)&f.i, sizeof( int ) );
    string::size_type tmpSize;
    file.read( (char*)&tmpSize, sizeof( string::size_type ) );
    f.str.resize( tmpSize );
    file.read( (char*)&f.str[0], tmpSize );
    

    Das ist nur ein Beispiel wie man es machen kann und sollte auf keinen Fall 1:1 in ein echtes Programm übernommen werden.

    Edit:

    Achso, das ganze schreibt man natürlich in Methoden von foo und dann ist es einfach von außen f.write( file ) und f.read( file ).

    Edit2:

    Mein Beispiel bezieht sich auf das Speichern der Binärdaten, da ich davon ausging, dass es darum ging. Ich persönlich würde eine Serialisierung mit op<< und op>> bevorzugen.



  • Ich glaube, wir beide haben sehr unterschiedliche Auffassungen von "einfach". Einfach heißt für mich nicht "sehr wenig Code zu schreiben" sondern "übersichtlicher Code, der keine komplexen Konzepte und keine potenziell gefährlichen Low-Level-Details benötigt".



  • Christian_c++ schrieb:

    ...
    Name - maximal 20 Zeichen array of character
    Vorname - maximal 20 Zeichen array of character
    ...

    nur mal so zur info: Die Lösung sollte mit char gelöst werden laut Aufgabenstellung, daher würde ich in diesem Fall kein string nehmen.

    gez. info



  • Konrad Rudolph schrieb:

    Ich glaube, wir beide haben sehr unterschiedliche Auffassungen von "einfach". Einfach heißt für mich nicht "sehr wenig Code zu schreiben" sondern "übersichtlicher Code, der keine komplexen Konzepte und keine potenziell gefährlichen Low-Level-Details benötigt".

    Ach jetzt plötzlich rausreden. :p 😉
    Hat nach

    file << strukt;
    

    mehr nach "sehr wenig Code zu schreiben" und nicht nach "übersichtlicher Code, der keine komplexen Konzepte und keine potenziell gefährlichen Low-Level-Details benötigt" ausgeschaut.

    Und das Operator überladen ist sicher nicht weniger komplex und auch nicht immer ungefährlich. Bei file << ist es noch ziemlich klar was << bedeutet, aber genau weiß man es nie. Außerdem musst du dann aufpassen, dass du keine element vergisst. Wenn C++ Reflection hätte, dann könnte man das schöner machen.

    Und die info von info sollte man auch beachten.



  • bedenke schrieb:

    Hat nach

    file << strukt;
    

    mehr nach "sehr wenig Code zu schreiben" und nicht nach "übersichtlicher Code, der keine komplexen Konzepte und keine potenziell gefährlichen Low-Level-Details benötigt" ausgeschaut.

    Hm, das war dann ein Missverständnis. Natürlich soll der Anwendungscode so kurz wie möglich sein; daher ist Operatorenüberladung ja gerade so schön (und daher ist die Einführung dieses Konzepts verkraftbar). Die Implementierung hingegen muss nicht kurz sein; sie wird ja nur einmal geschrieben.



  • Hi,
    danke das so viele etwas geschrieben haben, ich muss sagen, dass ich bisher nur Programme mit ein paar Schleifen und evt. einer Funktion geschrieben habe. Mit struct hatte ich bisher nioch nichts gemacht, deshalb tue ich mich so schwer.

    Ist es so richtig einen Datensatz zu erstellen?

    # include <iostream>
    using namespace std;
    
    struct Adresse
    {
    	long integer Postleitzahl;
    	char Stadt[20];
    	char Straße[20];
    };
    
    struct Datensatz
    {
    	char Name[20];
    	char Vorname[20];
        long integer Martikelnummer;
        Adresse adresse;
    	bool Geschlecht;
    	int Noten[10];
    };
    
    Datensatz a;
    a.Name="Mueller";
    a.Vorname="Hans";
    a.Martikelnummer=254781;
    a.adresse.Postleitzahl=64258;
    a.adresse.Stadt="Darmstadt";
    a.adresse.Straße="Darmstaedter Str";
    a.Geschlecht=1;
    a.Noten=5;
    


  • Bei char arrays solltest du besser mit strcpy den string "eintragen"

    strcpy(a.Name, "Mueller")
    

    Das mit = zuweisen geht nur bei std::string richtig, aber die sollst du ja nicht verwenden.
    Und wenn Noten ein array ist, dann kannst du da nicht nur eine Zahl zuweisen, sondern mehrere

    a.Noten[0]=5;
    a.Noten[1]=1;
    a.Noten[2]=3;
    


  • Hi,
    danke stimmt. Nur warum soll der name, vorname, stadt, straße ein array sein?


Anmelden zum Antworten