char Verständnis bei der Eingabe

Gast #5066873
Kurze frage zu char mit c++:

Wenn ich eine Eingabe tätigen möchte,  geht das mit findet. Aber wenn 
ich lediglich cin nutze,reicht die angabe des array:

char name[30];
cin >> name;
cout << name ;

Das char array "name" liefert ja die anfangsadresse. Wenn ich aber cin>> 
name[0] schreibe, geht das nur wenn ich den Adress Operator davor 
schalte. Verstehe ich das richtig?

Dann habe ich noch eine Frage zu cin.ignore. Wenn ich das verwende, wird 
mein erster Buchstabe angeschnitten, ohne gibt es aber eine 
Endlos-Schleife
Michael schrieb:
> Kurze frage zu char mit c++:
>
> Wenn ich eine Eingabe tätigen möchte,  geht das mit findet.
?

> Aber wenn
> ich lediglich cin nutze,reicht die angabe des array:
>
> Das char array "name" liefert ja die anfangsadresse.

Es liefert sogar auch noch den Typ des Arrays. Und daran kann der 
überladene Operator >> dann erkennen, um was es geht. Konkret wird wenn 
du ein char-array übergibst, diese Überladung ausgeführt:
1
basic_istream<_Elem, _Traits>& operator>>(
2
    basic_istream<_Elem, _Traits>& _Istr, _Elem *_Str)

Und die liest von der Konsole bis ein EOF oder whitespace (enter) 
Zeichen kommt. Und zwar auch, wenn dein buffer gar nicht lang genug ist. 
Das heißt, du kannst in einen char[3] auch 10 Zeichen einlesen. Und dann 
gibt es einen Buffer overflow, darauf sollte man also achten.

> Wenn ich aber cin>>
> name[0] schreibe, geht das nur wenn ich den Adress Operator davor
> schalte. Verstehe ich das richtig?

&foo[0] ist das gleiche wie foo, das ändert also nichts. Wenn du aber 
einen einzelnen Char einlesen willst, kannst du
1
std::cin >> foo[0];

benutzen, das ruft die folgende Version des Operators auf:
1
basic_istream<_Elem, _Traits>& operator>>(
2
    basic_istream<_Elem, _Traits>& _Istr, _Elem& _Ch)
Da wird also nur ein einzelner Char gelesen.

> Dann habe ich noch eine Frage zu cin.ignore. Wenn ich das verwende, wird
> mein erster Buchstabe angeschnitten, ohne gibt es aber eine
> Endlos-Schleife

Wie genau wendest du das an?
Gast
Hi, das hier löscht mir das erste Zeichen, laut meinem Buch sollte es 
aber funktionieren:

cout << "Bitte Spielernamen eingeben:" ;
cin.ignore();
cin.get(m_Name, 29);
cout << "Name: "<< m_Name << endl;
Gast
Hallo,


wenn du schon C++ benutzt, dann nimm für so was bitte std::string. Damit 
brauchst du dir keine Sorgen mehr über irgend welchen Speicher machen.
Michael schrieb:
> Hi, das hier löscht mir das erste Zeichen

Das wird daran liegen, dass die Standardparameter von istream.ignore 
angeben, dass mindestens 1 Zeichen entfernt wird. Ob da noch 
Zeilenumbrüche (\r, \n oder beides) im Buffer rumhängen wird vermutlich 
betriebssystemabhänhig sein. Kann also gut sein, dass es unter Linux 
funktioniert aber unter Windows nicht.
Mit den Streams die irgendwelche OS-Funktionen kapseln habe ich in C++ 
auch nur schlechte Erfahrungen gemacht, deshalb nutze ich da immer nur 
die stdio.h Funktionen, also scanf, printf, fopen, fread und so weiter.
Gast
Jetzt habe ich mal eine andere Frage:
1
char name[30];
2
cin >> name;

oder
1
char name[30];
2
cin >> &name[0];

funktioniert beides. Das heißt, dass das Array mir die Anfangsadresse 
bei der Eingabe liefert.

Wieso schreibt man bei einfachen Variablen nicht einfach auch:
1
int x;
2
cin >> &x;  // & Operator ist hier falsch, aber wieso? Bei Arrays wird doch auch die Anfangdadresse geliefert.

Im Vergleich zu C++ ist das in C auch nicht anders. Entweder schreibt 
man für scanf einfach "&x", also mit Adressoperator oder aber bei einem 
char-Array "name", dass ja die Anfangdadresse liefert. Warum ist bei C++ 
das ganze bei normalen Variablen ohne den Adressoperator?
Michael schrieb:
> funktioniert beides. Das heißt, dass das Array mir die Anfangsadresse
> bei der Eingabe liefert.

Richtig. Das Array IST zur Laufzeit auch nur noch seine Anfangsadresse. 
Die Information über die Größe, die du deklariert hast, ist zur Laufzeit 
nicht mehr vorhanden. Und zwar sowohl in C als auch in C++. Ein Array 
ist also nichts anderes als ein Pointer auf das erste Element.
1
char bla[10];
2
char *bla1 = bla; // bla1 ist zur Laufzeit komplett identisch zu bla

Jetzt ist auch einleuchtend, warum &bla[0] genau das gleiche ist wie 
bla. Denn der [] Operator dereferenziert den Pointer ein mal, und der 
Adressoperator macht das direkt wieder rückgängig.

> Wieso schreibt man bei einfachen Variablen nicht einfach auch:
>
>
1
> int x;
2
> cin >> &x;  // & Operator ist hier falsch, aber wieso? Bei Arrays wird 
3
> doch auch die Anfangdadresse geliefert.
4
>

Weil es eben keine Überladung des >> Operators für int-Arrays gibt. Wenn 
du wolltest, könntest du eine schreiben, dann würde das funktionieren.

> Im Vergleich zu C++ ist das in C auch nicht anders. Entweder schreibt
> man für scanf einfach "&x", also mit Adressoperator oder aber bei einem
> char-Array "name", dass ja die Anfangdadresse liefert. Warum ist bei C++
> das ganze bei normalen Variablen ohne den Adressoperator?

Weil der >> Operator für jeden zulässigen Typ eine eigene Überladung 
hat.

Wenn du cin >> x; machst wird intern eine Referenz auf x an die 
Einlesefunktion übergeben. Referenzen sind nochmal spezielle 
C++-Konstrukte ähnlich wie Pointer, die der aufgerufenen Funktion 
ermöglichen, die Variable zu ändern, ohne dass du einen Pointer 
übergeben hast (in C ginge das nicht).
Gast
Guten Morgen,
vielen Dank für die ausführliche Erklärung. Das heißt, dass durch das 
Überladen durch den Operator ">>" erkannt wird, um welchen Datentyp es 
sich handelt und der Nutzer muss sich nicht mehr darum kümmern, ob er 
eine Referenz einer Variablen oder die Variable selbst übergibt, 
korrekt?

In C war das nämlich anders, da hier die Adresse der Variablen übergeben 
werden sollte und zwar für alle Datentypen. Bei Arrays und Zeiger 
entfiel dies, weil das Array selbst, z.B. XYZ, bereits die 
Anfangsadresse liefert.
Michael schrieb:
> Guten Morgen,
> vielen Dank für die ausführliche Erklärung. Das heißt, dass durch das
> Überladen durch den Operator ">>" erkannt wird, um welchen Datentyp es
> sich handelt und der Nutzer muss sich nicht mehr darum kümmern, ob er
> eine Referenz einer Variablen oder die Variable selbst übergibt,
> korrekt?
Genau. Und weil es keinen Referenz Operator gibt, muss der Nutzer sich 
auch darum nicht kümmern. Wenn die aufgerufene Funktion oder der 
Operator eine Referenz erwartet, dann wird die Variable automatisch 
referenziert.

> In C war das nämlich anders, da hier die Adresse der Variablen übergeben
> werden sollte und zwar für alle Datentypen. Bei Arrays und Zeiger
> entfiel dies, weil das Array selbst, z.B. XYZ, bereits die
> Anfangsadresse liefert.
jap
Gast
Felix U. schrieb:
> Mit den Streams die irgendwelche OS-Funktionen kapseln habe ich in C++
> auch nur schlechte Erfahrungen gemacht, deshalb nutze ich da immer nur
> die stdio.h Funktionen, also scanf, printf, fopen, fread und so weiter.

Aber das sind C-Wrapper, die die eigentlichen OS Funktionen kapseln 
(open/read/write unter Unix, CreateFile, ReadFile, WriteFile unter 
Windows).
Die Bedienung der io streams ist für C Programmierer ungewohnt, aber die 
können genau so viel und sind dabei auch noch Typ sicher - wenn man den 
Typ einer Variablen ändert passt sich bei cout die Ausgabe automatisch 
an, bei printf nicht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.