Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

1

17.01.2011, 20:17

Probleme beim Öffnen und Beschreiben von Binär Dateien

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    struct Score
    {
        std::string name;
        long points;
        std::string date;
    };

void Highscores::loadHighscores()
{
    ofstream dataCreate ("Highscores.bin", ios::out | ios::binary);
    if(dataCreate==NULL)
        dataCreate << 0 << endl;
    dataCreate.close();

    char buffer[100];

    ifstream data ("Highscores.bin", ios::in | ios::binary);
    data.read(buffer,100);
    int scoresSize = atoi(buffer);
    for(int i = 0;i<scoresSize;i++)
    {
        Score s;

        data.read(buffer,100);
        s.name = buffer;

        cout << s.name << endl;

        data.read(buffer,100);
        s.points = atoi(buffer);

        data.read(buffer,100);
        s.date = buffer;

        scores.push_back(s);
    }
    data.close();
}

void Highscores::saveHighscores()
{
    ofstream data ("Highscores.bin", ios::out | ios::binary);

    int scoresSize = scores.size();
    data << scoresSize << endl;
    for(int i = 0;i<scoresSize;i++)
    {
        data << scores[i].name << endl;
        data << scores[i].points << endl;
        data << scores[i].date << endl;
    }
    data.close();
}


Sehr geehrtes Forum, wenn ich im vector scores ein paar Scores adde, und diese dann mit der Methode saveScores speichere und die Datei Higscores.bin mit nem Editor öffne, sind die Daten absolut unverschlüsselt, und wenn ich die Daten dann ausgeben lasse, nachdem ich sie mit der Methode loadHighscores geladen habe, dann kann der mir auch nichts ausgeben, weil er die Datei nicht lesen kann, was mache ich denn falsch? Kann mir einer helfen?

M.f.G. Developer_X
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

2

17.01.2011, 20:54

Warum sollten die Daten auch "verschlüsselt" in der Datei stehen? Du schreibst sie doch ganz normal rein.

Dein ofstream in loadHighscore() ergibt nicht wirklich Sinn... du öffnest die Datei, schreibst eine 0 rein (dataCreate ist nie 0), schließt sie und öffnest die Datei und liest aus?

3

17.01.2011, 21:08

du öffnest die Datei, schreibst eine 0 rein (dataCreate ist nie 0)

Du meintest wohl "schreibst keine 0 rein", denn wie du schon richtig gesagt hast müsste dafür dataCreate gleich NULL sein und wenn dem so ist, dann kann ganz sicher nicht in die Datei geschrieben werden.

Developer_X, du solltest dir wohl noch das ein oder andere Tutorial dazu anschauen. An einigen Stelle hakts bei deinem Quellcode noch. Insbesondere das Auslesen der Daten wird so nicht funktionieren.

Außerdem solltest du vielleicht mit hilfe von Rückgabewerten dein Programm und dann auch den Benutzer wissen lassen ob etwas schief ging und wenn ja, an welcher Stelle. Gerade wenn ein Programm Dateien erstellen oder lesen soll kann es an jeder Ecke scheitern. (Datei kann nicht erstellt / gelesen werden, falsches Format, ...)

Gruß
SaRu_

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

4

17.01.2011, 21:21

Du meintest wohl "schreibst keine 0 rein"


Ja meinte ich ^^ Da ist wohl ein "nie" in der Leitung hängen geblieben ^^

5

17.01.2011, 23:03

Wenn du binär schreiben willst, musst du ofstream data.write(...) benutzen, mit den << kannst du nicht binär schreiben.

lg chaia

6

17.01.2011, 23:33

Nja wenn du Strings binär schreiben willst, solltest du dir die länge speichern, damit du dann entsprechend wieder auslesen kannst. Dann geht das. Dann sowohl schreiben als auch lesen über write/read. Flag entsprechend setzen und schon kanns losgehen ;)
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

7

18.01.2011, 14:52

OK, danke erst einmal, ich werde eure Verbesserungsvorschläge so einfügen.

Ich mache das mit dem write 0, weil wenn keine Datei existiert, mit dem Namen "..bin" dann soll sie erstellt werden, was auch passiert, und dann eine 0 rein, dann auslesen, so soll das gemeint sein.

M.f.G. Developer_X und danke
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

8

18.01.2011, 15:12

Dann ist das aber immer noch der falsche Weg, wenn du überprüfst ob das ofstream-Objekt gleich NULL ist.


Auszug aus einer C++ Referenz :

Zitat

If the constructor is not successful in opening the file, the object is still created although no file is associated to the stream buffer and the stream's failbit is set (which can be checked with inherited member fail).

Aber warum erstellst du in der Funktion loadHighscore() eine Datei, die nichts als eine 0 enthalten soll und ließt die dann aus, wenn du doch schon weißt, dass im Grunde nichts drin steht?! Von einer Funktion die den Highscore laden soll würde man wohl nie erwarten, dass sie eine Datei anlegt. Also solltest du einfach prüfen ob eine Datei existiert, wenn ja probieren sie zu laden, wenn nein, dann einfach gar nichts machen oder deine Liste mit irgendwas füllen, was du willst. Aber keine Datei einlesen und schon gar keine anlegen, das solltest wirklich nur in der Funktion tun, die einen Highscore schreibt.

Gruß
SaRu_

Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

9

18.01.2011, 15:22

Gut ich habe eure Hilfen mit eingebaut, doch leider gibt es immer noch Fehler, und Probleme, und zwar kommen keine Fehlermeldungen, aber es werden die Profile die geadded wurden nicht ausgegeben.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void Highscores::loadHighscores()
{
    ofstream dataCreate ("Highscores.bin", ios::out | ios::binary);
    if(dataCreate==NULL)
        dataCreate << 0 << endl;
    dataCreate.close();

    char buffer[100];

    ifstream data ("Highscores.bin", ios::in | ios::binary);
    data.read(buffer,100);
    int scoresSize = atoi(buffer);

    int size;
    for(int i = 0;i<scoresSize;i++)
    {
        Score s;

        data.read(buffer,100);
        size = atoi(buffer);

        data.read(buffer,size);
        s.name = buffer;

        cout << s.name << endl;

        data.read(buffer,100);
        s.points = atoi(buffer);

        data.read(buffer,100);
        size = atoi(buffer);

        data.read(buffer,size);
        s.date = buffer;

        scores.push_back(s);
    }
    data.close();
}

void Highscores::saveHighscores()
{
    ofstream data ("Highscores.bin", ios::out | ios::binary);

    int scoresSize = scores.size();
    data.write(toCharArray(scoresSize).c_str(),100);
    for(int i = 0;i<scoresSize;i++)
    {
        data.write(toCharArray(static_cast<int>(scores[i].name.size())).c_str(),100);
        data.write(scores[i].name.c_str(),100);
        data.write(toCharArray(scores[i].points).c_str(),100);
        data.write(toCharArray(static_cast<int>(scores[i].date.size())).c_str(),100);
        data.write(scores[i].date.c_str(),100);
    }
    data.close();
}


Frage 1:
Ich habe schon die Datei erstellt, und in ihr sind schon alle Daten, die wurde mit saveHighscores gespeichert.
Nun wenn ich sie auslese, seht ihr ja die cout anweisung, die eigentlich den Namen der Score ausgeben sollte, was aber leider nicht
passiert, wo mache ich denn den Fehler beim einlesen, ich speichere extra die länge der Strings.

Hinweis:
Die Methode toCharArray habe ich mir selbstgeschrieben, der kann man einen int oder long überweise, und die Methode liefert dann einen string zurück.

Frage 2:
Du hattest mir vorhin die Hilfe gegeben, SaRu, und zwar dass ich fail() benutzen soll, ich weiß jetzt aber nicht wie ich das in meinem Code umsetzten soll, etwa so?
(Ausschnitt aus dem Code)

C-/C++-Quelltext

1
2
3
4
    ofstream dataCreate ("Highscores.bin", ios::out | ios::binary);
    if(ios::fail())
        dataCreate << 0 << endl;
    dataCreate.close();



Danke für eure Antworten und Hilfen,
m.f.G. Developer_X
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

10

18.01.2011, 15:59

Hallo Developer_X,

zu deiner 2. Frage erstmal (habe etwas wenig Zeit heute, morgen Mathe Abitur-Klausur):

Die Funktion fail() musst du auch vom entsprechenden Objekt aufrufen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
ofstream dataCreate ("Highscores.bin", ios::out | ios::binary);
if(dataCreate::fail())
{  
    // Es konnte keine Datei Highscore.bin geöffnet oder erstellt werden und somit kann das ofstream-Objekt nicht zum Schreiben benutzt werden. Also Fehler!
}
else
{
    // Die Datei Highscore.bin wurde entweder geöffnet (falls sie bereits existierte) oder neu angelegt (falls nicht). Jetzt und nur JETZT kann geschrieben / gelesen werden.
}


Das andere muss ich mir nachher mal anschauen oder jemand anderes machts. ;)

Gruß
SaRu_

Werbeanzeige