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

R3sident3vil

Treue Seele

  • »R3sident3vil« ist der Autor dieses Themas

Beiträge: 177

Wohnort: 1010010

Beruf: Selbstständig

  • Private Nachricht senden

1

24.05.2007, 22:27

Schwierige Situation

Hallo Herrschaften,

ich habe ein Problem, und zwar, es geht darum Variablen, die in einer Struktur deklariert worden sind, in meiner sogenannten Save-Datei abzuspeichern. Das Abspeichern erfolgt normal, aber nach dem Laden stellt sich heraus, dass nur 4 Zeichen einer längeren Eingabe gespeichert wurden.

Die Struktur sieht in meinem Code so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
struct Player
{
   unsigned int alter;
   unsigned int level;
   int Erfahrung;
   char name[256];
   char nachname[256];
   char rasse[256];
   char passwort[256];
};


und so sieht der Speichervorgang aus:

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
extern Player Charakter;

void Profil_Speichern(void)
{
  Charakter.level = 1;
  Charakter.Erfahrung = 0;
  cout << "Unter welchem Namen m\224chtest du deine Charakterinforamtionen \nspeichern? :";
  std::cin >> dateiname;
  dateiname.insert(0, "Data\\Saves\\");
  if (! (dateiname.substr(dateiname.length()-4)==".sav"))
  {
    dateiname.append(".sav");
  }
  std::ofstream Save(dateiname.c_str(), std::ios::binary);
  cout << "Datei wird unter '" << dateiname << "' gespeichert...\n";
  cout << endl;
  Sleep (500);
  Save.write ((char*) &Charakter.name, sizeof (&Charakter.name));
  
  Save.write ((char*) &Charakter.nachname, sizeof (&Charakter.nachname));
  
  Save.write (reinterpret_cast<char*> (&Charakter.alter), sizeof (unsigned int));
  
  Save.write ((char*) &Charakter.rasse, sizeof (&Charakter.rasse));
  
  
  Save.write ((char*) &Charakter.passwort, sizeof (&Charakter.passwort));
  Save.write (reinterpret_cast<char*> (&Charakter.level), sizeof (unsigned int));
  Save.write (reinterpret_cast<char*> (&Charakter.Erfahrung), sizeof (int));
  
  Save.close ();
 
  std::ifstream Load (dateiname.c_str(), std::ios::binary);
  if( GetFileAttributes( dateiname.c_str() ) == 0xFFFFFFFF )
  {
    cout << "It appeared an error during save-process." << endl;
    Sleep (2500);
    Vormenue ();
  }
  else cout << "Profile-Save has been completed successfully! \1  \2 \n";
  Sleep (2000);
  cout << endl;
  Willkommen ();
}


Was könnte der Fehler sein?

MfG M.O.O.

EDIT: Z.b: Ich gebe den Namen Siegfred Schulz ein, speichere, und beim Laden des Profils werde ich als Sieg Schu begrüßt. :shock:
Kaum ist Linux wieder da, schon gehts meinem Rechner wunderbar, denn Linux ist die beste Medezin.

Olischewsky Arts

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

24.05.2007, 22:35

ich denke das problem ist, dass sizeof(&Character.name) 4 ist ;)
lass bei den ganzen sizeof das & drinnen weg und sollte gehen.

btw: warum verwendest du einmal reinterpret_casts und dann wieder C casts?
außerdem frag dich mal, ob da wirklich alle felder 256 zeichen lang sein müssen und wofür das unsigned bei alter und level ist!?

R3sident3vil

Treue Seele

  • »R3sident3vil« ist der Autor dieses Themas

Beiträge: 177

Wohnort: 1010010

Beruf: Selbstständig

  • Private Nachricht senden

3

24.05.2007, 23:06

1. Weiß jetzt nicht was du für C casts meinst.
2. Ich finde es nicht verkehrt, wenn man 256 Felder zur Verfügung stellt.
3. Das unsigned int ist bei Alter und Level gut, weil die beiden Variablen keine Werte, die < 0 sind annemen sollen.
Kaum ist Linux wieder da, schon gehts meinem Rechner wunderbar, denn Linux ist die beste Medezin.

Olischewsky Arts

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

4

25.05.2007, 06:58

Überleg doch mal, wo der Unterschied zwischen den zwei folgenden Zeilen liegt:

C-/C++-Quelltext

1
2
3
4
char buffer[256];

Save.write (buffer, 256);
Save.write (reinterpret_cast<char*> (&buffer), sizeof (char*));


... erst denken, dann weiterlesen.... ;)

Die "write" Methode bekommt einen Zeiger auf einen Speicherblock, ab dem die zu speichernden Daten stehen, sowie einen Zähler, wieviele Bytes geschrieben werden.

Version 1 bekommt also einen Zeiger auf den Anfang der 256 vorgesehen Zeichen und schreibt diese uninterpretiert auch in den Stream.

Version 2 bekommt einen Zeiger auf den eben genannten Zeiger und speichert diesen in den Stream.

Wenn du das genauso lädst, hätte das gut auch einfach abstürzen können.
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

5

25.05.2007, 07:37

Zitat von »"R3sident3vil"«

1. Weiß jetzt nicht was du für C casts meinst.
2. Ich finde es nicht verkehrt, wenn man 256 Felder zur Verfügung stellt.
3. Das unsigned int ist bei Alter und Level gut, weil die beiden Variablen keine Werte, die < 0 sind annemen sollen.


1. C-Casts:

C-/C++-Quelltext

1
2
const char* p = ( const char*)( &irgendwas );
int i = int( irgendwasandres );


C++-Casts:

C-/C++-Quelltext

1
2
3
4
static_cast<>()
dynamic_cast<>()
reinterpret_cast<>()
const_cast<>()


2. Schonmal Namen mit 256 Zeichen gesehen?

3. Wenn du einer unsigned Variablen -1 übergibst bekommst du den Maximalwert des Typs und das ist für ein Alter etwas viel, nicht? Und 2^16 oder 2^32 sind "etwas" überladen für Altersangaben...
@D13_Dreinig

6

25.05.2007, 15:01

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
void Profil::save() const
{
    Charakter.level     = 1;
    Charakter.Erfahrung = 0;
    std::cout << "Unter welchem Namen m\224chtest du deine Charakterinforamtionen\nspeichern? " << std::flush;
    std::string file_name;
    std::getline(std::cin, file_name);
    file_name.insert(0, "Data\\Saves\\");
    if (file_name.substr(file_name.length() - 4) != ".sav")
        file_name += ".sav";

    std::ofstream file_stream_o(file_name.c_str(), std::ios::binary);
    if (!file_stream_o)
        return;

    std::cout << "Daten werden in '" << file_name << "' gespeichert ..." << std::endl;
    file_stream_o.write(reinterpret_cast<char*>(&Charakter.name), sizeof(char) * Charakter.name.length());
    file_stream_o.write(reinterpret_cast<char*>(&Charakter.nachname), sizeof(char) * Charakter.nachname.length());
    file_stream_o.write(reinterpret_cast<char*>(&Charakter.alter), sizeof(unsigned int));
    file_stream_o.write(reinterpret_cast<char*>(&Charakter.rasse), sizeof(ENUM_RASSE));
    file_stream_o.write(reinterpret_cast<char*>(&Charakter.passwort), sizeof(char) * Charakter.passwort.length());
    file_stream_o.write(reinterpret_cast<char*>(&Charakter.level), sizeof(unsigned int));
    file_stream_o.write(reinterpret_cast<char*>(&Charakter.Erfahrung), sizeof(int));
     
    std::cout << "Profile-Save has been completed successfully! \1  \2 " << std::endl;
} 
;)
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

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

7

25.05.2007, 15:19

C-/C++-Quelltext

1
sizeof( char ) *


Kannste stecken. Das is unnötig! :)
@D13_Dreinig

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

25.05.2007, 15:24

C-/C++-Quelltext

1
reinterpret_cast<char*>


genauso wie das :p

9

25.05.2007, 15:36

jap ... hab sizeof(char) nur geschrieben, damit er weiß dass man eig., wenn char nicht 1 groß wäre, sizeof nutzen müsste ... d.h. sizeof(wchar_t) * string.length() bsw.

und das mitm reinterpret_cast ... hab ka was er da fürn typ als ausgangswert hat ... aber seh gerade die struct ... dann stimmt es natürliche
wobei @ ResidentEvil: nutz std::string statt char-array ...
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

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

10

25.05.2007, 16:00

Zitat von »"Deviloper"«

C-/C++-Quelltext

1
2
3
4
5
6
7
void Profil::save() const
{
    // ...

    file_stream_o.write(reinterpret_cast<char*>(Charakter.name), sizeof(char) * Charakter.name.length());
    file_stream_o.write(reinterpret_cast<char*>(Charakter.nachname), sizeof(char) * Charakter.nachname.length());
    // ...

} 

solange es sich hier um Arrays handelt rate ich von dem & ab ;)

Werbeanzeige