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

1

24.04.2009, 14:12

Aufgabe Kapitel 5

Hi,

hab mich erstmal hier angemeldet, nachdem ich stundenlang in meiner Lösung für die Aufgabe 5 nach dem Fehler gesucht habe
weshalb das Programm nicht funktioniert und feststellen musste:
Selbst die Musterlösung ist fehlerhaft.

Erstes Problem: Warum steht das "cin.ignore ();" noch vor dem "cin.get ..."?
Es kam in den Listings vorher immer erst danach...
Dies hatte nämlich zur Folge, dass immer, nachdem ich meine Werte eingegeben hatte
das Programm abgestürzt ist...
Woher hätte ich das wissen sollen?

Zweitens:
Der Fehler (?) der auch in der Musterlösung steckt:
Gebt mal als Namen bei der Zuweisung des Feldes mehr als 29 Buchstaben ein...
Richtig - Absturz ;)
Ich dachte eigentlich genau das wäre die "Aufgabe" von "cin.get"..?
Ich hab nämlich (nachdem ich in der Lösung geguckt habe und gesehen habe, dass das "cin.ignore" vorher kommt) daran ständig rumprobiert,
da ich ja wollte, dass mein Programm möglichst absturz-sicher ist.

Ansonsten ein klasse Buch! ;)

MfG,
Rabbit

Lerikson

Alter Hase

Beiträge: 412

Wohnort: nördlich von Hamburg

Beruf: Schüler

  • Private Nachricht senden

2

24.04.2009, 15:57

Willkommen im Forum (ich hoffe das darf man hier auch als Nicht-Moderator sagen... :D ) Jack_Rabbit!

Also vielleicht kannst du mal den Quellcode posten dann könnte man sich das besser angucken

3

24.04.2009, 16:08

Hallo und herzlich Willkommen im Forum :!:

Wenn bei cin.get(...,29) steht, dann kann es auch maximal 29 Zeichen
"aufnehmen". Dann ist doch klar, dass das Programm nicht geht, wenn man
mehr als 29 Zeichen eingibt, oder?

Und cin.ignore() löscht einfach nur den Eingabepuffer. ;)
MfG Shiver!

„Ideen sind nur Ausgangspunkte. Um zu wissen, was man zeichnen will, muss man zu zeichnen anfangen.“ Pablo Picasso

Ibot Development - Mein Weg zum eigenen 2D RPG

4

24.04.2009, 16:19

Gerne!


Zum besseren verständniss:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Konstanten

const int Hoehe = 5;
const int Breite = 5;


//Strukturen

struct S_Felddaten
{
    char Name[30];
    bool Feld;
};

//Arrays

S_Felddaten Spielfeld[Hoehe][Breite];


Der Teil um den es geht:

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
void BesetzeFeld ()
{
    //Variablen

    //

    int x;
    int y;

    // x-Wert abfragen

    do
    {
        cout << "x - Position (1-" << Breite << "): ";
        cin >> x;

        cout << endl;

    } while ((x<1) || (x>Breite));

    //y-Wert abfragen

    do
    {
        cout << "y - Position (1-" << Hoehe << "): ";
        cin >> y;

        cout << endl;

    } while ((y<1) || (y>Hoehe));

    // Index korrigieren

    x--;
    y--;

    // Name für Feld eingeben

    cout << "Name: ";
    cin.ignore ();
    cin.get (Spielfeld[y][x].Name, 29);
    cout << endl;

    // Feld "besetzen"

    Spielfeld[y][x].Feld = true;

}


Nun hatte ich das "cin.ignore();" nach "cin.get (Spielfeld[y][x].Name, 29);" stehen, was zum Absturz geführt hat.
Stand aber bisher im Buch halt immer danach :S

Und wenn man nun im laufenden Programm mehr als 29 Buchstaben eingibt stürzt das ganze auch ab. Was ja, so wie ich das verstanden hatte, nicht Sinn der Sache ist ^^


Hier noch der Code aus der Musterlösung:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Strukturen

//

struct S_FeldInfo
{
    bool Besetzt;
    char Name[30];
};

// Variablen und Konstanten

//

const int Breite = 5;
const int Hoehe = 5;
S_FeldInfo Spielfeld[Breite][Hoehe];

// Prototypen

//

void LoescheSpielfeld ();
void ZeigeSpielfeld ();
void ZeigeFelddaten ();
void BesetzeFeld ();


...

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
void BesetzeFeld ()
{
    int x = 0;
    int y = 0;

    // Koordinaten abfragen

    do
    {
        cout << "x-Position (1-" << Breite << "): ";
        cin >> x;
    } while (x<1 || x>Breite);

    do
    {
        cout << "y-Position (1-" << Hoehe << "): ";
        cin >> y;
    } while (y<1 || y>Breite);

    // Name abfragen und Felddaten füllen

    cout << "Name: ";
    cin.ignore ();
    cin.get (Spielfeld[x-1][y-1].Name, 29);
    Spielfeld[x-1][y-1].Besetzt = true;

} // BesetzeFeld


Danke für den herzlichen Empfang :D
MfG

5

24.04.2009, 16:21

Zitat von »"Shiver"«


Wenn bei cin.get(...,29) steht, dann kann es auch maximal 29 Zeichen
"aufnehmen". Dann ist doch klar, dass das Programm nicht geht, wenn man
mehr als 29 Zeichen eingibt, oder?


Laut Buch: "... wird der Rest einfach abgeschnitten, damit eben kein dahinterliegender Speicher überschrieben wird" (so oder ähnlich ;) )

Was übrigens in einem Beispiel kurz davor auch wunderbar funktioniert hatte... Deswegen bin ich ja so verwirrt ^^

6

24.04.2009, 17:11

probier mal, statt cin.get(Spielfeld[y][x].Name, 29) cin.getline(Spielfeld[y][x].Name, 30) zu verwenden.
Der Unterschied:
get liest einfach die zeichen in den angegebenen Speicherbereich, ohne sich um nullterminierung zu kümmern.
getline liest in den angegebenen speicherbereich, aber ein zeichen weniger als angegeben, stattdessen wird als leztes der nullterminator eingefügt.
bei get müsstest du nämlich ansonsten noch das letzte zeichen von hand auf 0 setzten, sonst gibts das nächste mal, wenn du irgendwas mit dem array machst, probleme (die durchaus einen absturz bewirken können).
übrigens mit einigen compilern nur im releasemodus, da sie im debugmodus auch variablen, die normalerweise unintialisiert sind, mit 0 initialisieren.

Werbeanzeige