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

30.01.2011, 17:31

Aufgabenstellung 5.11 Finde den Fehler nicht

Hallo

Ich bin gerade dabei das Programm für die Aufgabenstellung 5.11 zu schreiben und habe einen fehler eingebaut. Aber nach langer suche habe ich immer noch kein Fehler gefunden könntet ihr mir bitte helfen den fehler zu finden. ich wollte gerade den code einfügen mit dem Befehl C-/C++-Quelltext einfügen und es geht irgendwie nicht dann füg ich den quelltext halt so ein

Hier der Quelltext



#include <iostream>

using namespace std;

int Spielfeld ();
int Feldbesetzen ();
int Felddaten ();
int Löschen ();

struct S_Gebiet //Struktur global
{
bool Besetzt;
char Gebietsname[20];
};

S_Gebiet Gebiet[1]; //Struktur

int main () // Hauptprogramm
{
int Menü;

cout << " 1 - Spielfeld anzeigen " << endl; //Menü <----
cout << " 2 - Feld besetzen " << endl;
cout << " 3 - Felddaten anzeigen " << endl;
cout << " 4 - Spielfeld loeschen " << endl;
cout << " 5 - Programm beenden " << endl; //---->

cin >> Menü;

switch (Menü) //Ausgabe der Funktionen
{
case (1):
{
Spielfeld ();

}break;

case (2):
{
Feldbesetzen ();

}break;

case (3):
{
Felddaten ();

}break;

case (4):
{
Löschen ();

}break;

case (5):
{
cout << " F ";

}break;

default:
{
cout << "Falsche Eingabe\n\n";
}
}while ( Menü != 'b' && Menü != 'B' ); //Beenden

return 0;
}



int Spielfeld ()
{
cout << "L";
}

int Feldbesetzen ()
{
cout << "x-Position (1-5): ";
cout << "y-Position (1-5): ";
cout << "Name : ";
cin >> cin.get (Gebiet[20].Gebietsname, 19);
}

int Felddaten ()
{
cout << "L";
}

int Löschen ()
{
cout << "L";
}

2

30.01.2011, 18:01

Du kannst keine globalen Objekte erstellen, das muss in main oder einer anderen Funktion geschehen.
Außerdem brauchst du kein Array, wenn du nur 1 Objekt willst. Also lass einfach das [1] weg.

lg chaia

3

30.01.2011, 19:06

Du kannst keine globalen Objekte erstellen, das muss in main oder einer anderen Funktion geschehen.
lg chaia


Sicherlich kann man das, sonst könnte er sie ohne Pointer o.ä. nicht in seinen Funktionen verwenden.

C-/C++-Quelltext

1
cin >> cin.get (Gebiet[20].Gebietsname, 19);

-->

C-/C++-Quelltext

1
cin.get (Gebiet[20].Gebietsname, 19);


Deinen Funktionen musst du noch einen Rückgabewert zuweisen, wenn du sie nicht mit void deklarierst

Allerdingst verstehe ich den Sinn deiner S_Gebiet Gebiet[1]; Variable auch nicht ... ICh glaube eher, dass du das so gemeint hast:

C-/C++-Quelltext

1
2
3
4
5
6
7
struct S_Gebiet //Struktur global
{
bool Besetzt;
char Gebietsname[20];
};

S_Gebiet Gebiet[21]; //Struktur


denn sonst könntest du hier nicht auf das 20. Element deiner Struktur zugreifen

C-/C++-Quelltext

1
cin.get (Gebiet[20].Gebietsname, 19);


Das ist mir jz auf die Schnelle aufgefallen ... Solltest du aber ohnehin fehlermeldungen bekommen haben ...

EDIT: Wegen den Code Tags ... du kannst die machen, indem du den Code innerhalb der [ cpp ] [ /cpp ] Tags schreibst (Die Tags entweder selber schreiben oder über den Button C-/C++-Quelltext hohlen ;))

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Ombalat« (30.01.2011, 19:12)


4

01.02.2011, 17:51

Ich habe nochmal eine Frage der Code ist jetzt "richtig" aber ich will jetzt in der Funktion int Feldbesetzen () einen namen eingeben aber die funktion cin.get überspringt es einfach und ich kann keinen namen eingeben was ist falsch?

int Feldbesetzen

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
int Feldbesetzen ()
{
    cout << "x-Position (1-5): \n";
    cout << "y-Position (1-5): \n";
    cin.get ( Gebiet.Gebietsname, 19 );
    cout << "Name : ";

    return 0;
}



ganzer quellcode

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>

using namespace std;

int Spielfeld ();
int Feldbesetzen ();
int Felddaten ();
int Löschen ();

struct S_Gebiet                 //Struktur global
{
    bool Besetzt;
    char Gebietsname[20];
};

S_Gebiet Gebiet;                //Struktur

int main ()                     // Hauptprogramm
{
    int Menü;

    cout << " 1 - Spielfeld anzeigen " << endl;     //Menü <----
    cout << " 2 - Feld besetzen " << endl;
    cout << " 3 - Felddaten anzeigen " << endl;
    cout << " 4 - Spielfeld loeschen " << endl;
    cout << " 5 - Programm beenden " << endl;       //---->

    cin >> Menü;

    switch (Menü)      //Ausgabe der Funktionen
    {
      case (1):
      {
        Spielfeld ();

      }break;
    
      case (2):
      {
        Feldbesetzen ();

      }break;

      case (3):
      {
        Felddaten ();

      }break;

      case (4):
      {
        Löschen ();

      }break;

      case (5):
      {
        cout << " F ";

      }break;

      default:
        {
        cout << "Falsche Eingabe\n\n";
        }
    }while ( Menü != 'b' && Menü != 'B' );        //Beenden

    return 0;
}



int Spielfeld ()
{
    cout << "L";

    return 0;
}

int Feldbesetzen ()
{
    cout << "x-Position (1-5): \n";
    cout << "y-Position (1-5): \n";
    cin.get ( Gebiet.Gebietsname, 19 );
    cout << "Name : ";

    return 0;
}

int Felddaten ()
{
    cout << "L";

    return 0;
}

int Löschen ()
{
    cout << "L";

    return 0;
}

5

01.02.2011, 18:31

Versuchs mal mit nem cin.ignore() vor dem cin.get() ;)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
int Feldbesetzen ()
{
    cout << "x-Position (1-5): \n";
    cout << "y-Position (1-5): \n";
    cout << "Name : ";
    cin.ignore();
    cin.get ( Gebiet.Gebietsname, 19 );

    return 0;
}


Liebe Grüße,
Ombalat

Obstsalat

Frischling

Beiträge: 8

Beruf: Student

  • Private Nachricht senden

6

12.06.2012, 11:38

Versuchs mal mit nem cin.ignore() vor dem cin.get() ;)

C-/C++-Quelltext
1
2
3
4
5
6
7
8
9
10

int Feldbesetzen ()
{
cout << "x-Position (1-5): \n";
cout << "y-Position (1-5): \n";
cout << "Name : ";
cin.ignore();
cin.get ( Gebiet.Gebietsname, 19 );

return 0;
}


Liebe Grüße,
Ombalat

Hallo,

Eine Frage Zwei Fragen hätte ich dazu.

Im Buch steht, dass man mit

C-/C++-Quelltext

1
cin.ignore();

Den Lesezeiger zurücksetzen muss, um mit

C-/C++-Quelltext

1
cin.get();

arbeiten zu können.

1. Warum muss man nicht nach jedem cin-Befehl cin.ignore(); schreiben?

2. Warum muss nach cin.get(); kein cin.ignore(); geschrieben werden? Setzt sich der Lesezeiger dort automatisch zurück?

Danke

Viele Grüße

Obstsalat

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Obstsalat« (12.06.2012, 11:48)


S4My

unregistriert

7

12.06.2012, 22:08

Warum das verschieden ist, ist eigentlich simpel: es sind andere Methoden :D .
Die einfache Verwendung von cin im Zusammenhang mit dem ">>" Operator fängt an bei einem Zeichen ungleich dem Leerzeichen zu lesen und liest bis zu einem dieser Zeichen weiter, soweit ich das in Erinnerung habe, Werte ein.
cin.get() seinerseits liest Werte bis zum folgenden <Return> ein, also dem einfachen Enter-Tastendruck.

Nun habe ich mich ein wenig schlau gemacht, fängt gut an was, wie bei den Profis ^^ , und gelesen, dass eingelesene Newline-Character( == '\n' ) im String drinbleiben.
OK, viel kam bisher noch nicht rüber, jetzt stelle man sich jedoch vor was passieren würde, wenn ich einen String habe, welcher nur aus "\n" besteht, aber Funktionen wie cin.get() eben bei diesem Zeichen den Lesevorgang beenden. Der Sinn cin.ignore()´s ist es nun eben diesen Charakter zu, naja, ignorieren, wie der Name schon vermuten lässt. Etwa so wie Pointer immer nach dem delete sicherheitshalber auf NULL gesetzt werden, damit keine Fehler auftreten.

Auf deinen Quelltext bezogen hat man dann folgende Begebenheit: Zeile 28 wird mit cin ein Wert eingelesen, der wie ich annehme durch einen Enterdruck bestätigt wird. Nun hat man also den Salat. Das Newline-Zeichen wurde gelesen und wird auch nicht gelöscht.

Was noch die Sache angeht mit der Verwendung: prinzipiell ist es so, man müsste es auch machen, also die Funktion nach bzw. zur Sicherheit vor dem "gewöhnlichen" Einlesen anwenden. Bei der Methode welche mit ">>" angesprochen wird, wird allerdings nichts gelesen ehe der String nicht komplett ist, also kann hier nicht abgebrochen werden. Wobei ich ergänzend sagen muss, letzere Aussage hat sich mein Gehirn aus dem vorhergehenden Text und meiner gefürchteten Erfahrung selbst zusammen gesponnen, also eine Vermutung :) .

Ich hoffe es war hilfreich!

Mlg
S4My

Obstsalat

Frischling

Beiträge: 8

Beruf: Student

  • Private Nachricht senden

8

13.06.2012, 12:12



Warum das verschieden ist, ist eigentlich simpel: es sind andere Methoden :D .
Die einfache Verwendung von cin im Zusammenhang mit dem ">>" Operator fängt an bei einem Zeichen ungleich dem Leerzeichen zu lesen und liest bis zu einem dieser Zeichen weiter, soweit ich das in Erinnerung habe, Werte ein.
cin.get() seinerseits liest Werte bis zum folgenden ein, also dem einfachen Enter-Tastendruck.

Nun habe ich mich ein wenig schlau gemacht, fängt gut an was, wie bei den Profis ^^ , und gelesen, dass eingelesene Newline-Character( == '\n' ) im String drinbleiben.
OK, viel kam bisher noch nicht rüber, jetzt stelle man sich jedoch vor was passieren würde, wenn ich einen String habe, welcher nur aus "\n" besteht, aber Funktionen wie cin.get() eben bei diesem Zeichen den Lesevorgang beenden. Der Sinn cin.ignore()´s ist es nun eben diesen Charakter zu, naja, ignorieren, wie der Name schon vermuten lässt. Etwa so wie Pointer immer nach dem delete sicherheitshalber auf NULL gesetzt werden, damit keine Fehler auftreten.

Auf deinen Quelltext bezogen hat man dann folgende Begebenheit: Zeile 28 wird mit cin ein Wert eingelesen, der wie ich annehme durch einen Enterdruck bestätigt wird. Nun hat man also den Salat. Das Newline-Zeichen wurde gelesen und wird auch nicht gelöscht.

Was noch die Sache angeht mit der Verwendung: prinzipiell ist es so, man müsste es auch machen, also die Funktion nach bzw. zur Sicherheit vor dem "gewöhnlichen" Einlesen anwenden. Bei der Methode welche mit ">>" angesprochen wird, wird allerdings nichts gelesen ehe der String nicht komplett ist, also kann hier nicht abgebrochen werden. Wobei ich ergänzend sagen muss, letzere Aussage hat sich mein Gehirn aus dem vorhergehenden Text und meiner gefürchteten Erfahrung selbst zusammen gesponnen, also eine Vermutung :) .

Ich hoffe es war hilfreich!

Mlg
S4My

Hi S4My,

vielen Dank für deine Ausführungen.

Mal sehen ob ich das richtig verstanden habe...

A) Mit dem cin-Befehl und dem Umleitungsoperator (">>") kann man Werte beginnend von einem Zeichen ungleich dem Leerzeichen bis zum Ende der Zeichenkette (wo entweder ein Leerzeichen folgt oder <return> gedrückt wird) einlesen.

Zitat

Text
Eingabe: AB CD EFGHI
Ausgabe: AB

Zahl

Eingabe: 1234 56789
Ausgabe: 1234
B) Mit der cin.get()-Funktion werden auch Leerzeichen eingelesen. Das heißt

Zitat

Text
Eingabe: AB CD EFGHI
Ausgabe: AB CD EFGHI

Zahl

Eingabe: 1234 56789
Ausgabe: 1234 56789
Soweit so schön.

Durch das Drücken der Enter-Taste (return) wird also das Newline-Character Zeichen '\n' mit gespeichert. Es wird als Endbedingung für den cin-Lesebefehl interpretiert, bleibt aber scheinbar irgendwie im Strom hängen (im String drinbleiben?). Dadurch, dass das '\n' noch im Strom steckt, wird die Funktion cin.get() blockiert, da er gar nicht erst mit Einlesen anfängt, da das sich im Strom befindende '\n' direkt als Endbedingung für die Funktion cin.get() interpretiert wird. Mit cin.ignore() kann man diesen Newline-Character "ausblenden" respektive ignorieren.

Meine Frage jetzt:

Warum wird der cin-Befehl und die cin.get()-Funktion nicht unabhängig voneinander behandelt? Das heißt, warum wird das Newline-Character-Zeichen '\n', welches mit cin eingelesen wird, nicht in der Zeichenkette selbst gespeichert und warum wird dann mit cin.get() nicht eine komplett neue Zeichenkette eingelesen?

Wenn mir das noch einer beantworten könnte, wäre es alles schick.

Danke

Liebe Grüße

Obstsalat

S4My

unregistriert

9

13.06.2012, 23:36

Vorsicht: Spekulation - An ;)

cin ist eine Instanz der Klasse iostream, oder einer der vielen anderen welche mit dieser zusammenhängen. Wie man es von Instanzen gewohnt ist so besitzen sie, natürlich sofern definiert, Variablen und Methoden. Hierbei kommt allerdings noch eine wahre Kunst C++´s zum Einsatz: Überladene Operatoren. cin an sich besitzt eine Variable welche die eingelesenen Werte aufnimmt. ">>" als auch "<<"( für cout ) sind an sich Bitoperatoren, welche ungefähr so verwendet werden:

C-/C++-Quelltext

1
2
unsigned int blablubb = 2 ;
blablubb << 2 ;

Nach dieser Auflistung an Befehlen hat "blablubb" nun den Wert 8. Wie, ganz einfach, zumindest solange es so ist wie ich es verstanden habe :D :

blablubb hat den Wert 2 zugewiesen bekommen == 0000 0010 in binärer Angabe.
Der Bitoperator verschiebt in die Richtung in die er zeigt alle Bits um die Anzahl der Schritte welche rechts angegeben wurden, also 0000 0010 wird zu
0000 1000 == 8. Dieses logische "in eine Richtung Daten schieben" wird wahrscheinlich der Anlass gewesen sein diese Operatoren zu überladen.

Also ist cin an sich kein Befehl. Mit dem Operator sprichst du eine Methode( == Funktion ) und mit ".get()" eine andere der Klasseninstanz an. Wie man es eben auch gewohnt ist von anderen Objekten ^^ .

Jetzt noch zu dem mit den Zeichenketten: der Newline-Character ist an sich ein nicht druckbares Zeichen, soll heißen er kann grafisch, zumindest ohne weitere Zeilen welche davon getrennt sind, nicht dargestellt werden. Gleiches gilt auch für das Leerzeichen. An dieser Stelle würde ich noch gerne hinzufügen, "cin>>" liest von dem ersten bis zum letzten druckbaren Zeichen, also nicht nur von Leerzeichen zu Leerzeichen, da habe ich etwas mit Worten gespart :) .
Mit cin.get() wird eine neue Zeichenkette eingelesen, allerdings nur solange nicht das "STOP"-Zeichen, so nenne ich es einmal, entdeckt wurde. Dieses kann übrigens auch manipuliert werden, beispielsweise durch einen Punkt ersetzt werden, wodurch das lesen eines Punktes zum Beenden führen würde. Diese wird jedoch in die eine dafür zuständige Variable der Instanz gespeichert.

Ich hoffe das klärt alle Fragen und am besten wäre es, wenn es dann auch noch richtig ist :D .

Mlg
S4My

Obstsalat

Frischling

Beiträge: 8

Beruf: Student

  • Private Nachricht senden

10

14.06.2012, 10:42

Danke S4My, du hast mir sehr geholfen!

Werbeanzeige