Problem bei verschachtelten while/if Anweisungen
-
SeppJ schrieb:
Hier gehen drei Dinge schief:
1. Nachdem eine Eingabe fehlgeschlagen ist, so befindet sich der Stream in einem Fehlerzustand und es schlagen alle weiteren Aktionen fehl, bis man sich darum kümmert (z.B. mit clear()).
2. Danach sind natürlich immer noch die Zeichen auf dem metaphorischen Lochstreifen, die zum Fehlschlag geführt haben. Da muss man sich auch drum kümmern, z.B. mit ignore().
3. In Zeile 16 steht bei dir ja wieder etwas aus dem Stream gelesen (oder wenigstens wird es versucht). Das ist bestimmt nicht die Logik, die du dir vorgestellt hast.So kann man das beispielsweise machen:
#include <iostream> #include <cctype> using namespace std; void skip_word(istream &in) { for (char c = in.peek(); in && isgraph(c); c = in.peek()) in.ignore(1); } int main() { int i; for (;;) { cin >> i; if (!cin && !cin.eof()) { cout << "Das war keine Zahl\n"; cin.clear(); skip_word(cin); } else break; } cout << "Zahl gelesen: " << i << '\n'; }Du wirst merken, dieses schon relativ komplexe Beispiel lässt noch viele Wünsche offen. Falls du vor hast, das weiter zu treiben und weitere Fehler abzufangen, lass dir gesagt sein, dass dies in die Richtung geht, ein eigenes GUI-Framework zu schreiben. Das gibt es aber schon längst und in viel besser.
Ich danke dir

Ich habe denke ich verstanden wie das ganze funktioniert.
Als erstes wenn das cin fehlschlägt benutzt man die cin.clear() Funktion um soweit ich richtig verstanden habe den Eingabebuffer zu leeren. Als nächstes übergibt man den stream an die selbst geschriebene Funktion welche jedes Zeichen des Streams von Anfang bis Ende ignoriert(löscht?).
Dadurch kann man es danach auch wieder neu einlesen ,und die if schleife wird nicht endlos ausgeführt.
Habe ich das soweit richtig verstanden , oder ist da etwas noch falsch an dem wie ich es aufgefasst habe?
-
Leider hast du so ziemlich alles falsch verstanden.
DerNoob1993 schrieb:
Ich habe denke ich verstanden wie das ganze funktioniert.
Als erstes wenn das cin fehlschlägt benutzt man die cin.clear() Funktion um soweit ich richtig verstanden habe den Eingabebuffer zu leeren.Es gibt keinen Eingabepuffer.
Als nächstes übergibt man den stream an die selbst geschriebene Funktion welche jedes Zeichen des Streams von Anfang bis Ende ignoriert(löscht?).
Es gibt keinen Anfang. Hier wird auch nicht bis Ende gelöscht. Man weiß normalerweise nicht einmal, ob es ein Ende gibt oder wann es kommt.
Dadurch kann man es danach auch wieder neu einlesen ,und die if schleife wird nicht endlos ausgeführt.
Es gibt keine if-Schleifen.
Noch einmal:
Es wird gelesen. Es wird geprüft, ob das Lesen erfolgreich war. Falls dies der Fall war: Fertig. falls das Lesen nicht erfolgreich war: Dann befindet sich der Stream in einem Fehlerstatus (das ist quasi die Definition von nicht erfolgreichem Lesen). Dieser wird mit clear aufgehoben. Damit signalisiert man dem Stream, dass man den Fehler erkannt hat und sich darum kümmern wird. Dann wird die selbstgeschriebene Funktion aufgerufen. Diese setzt den Stream so lange zeichenweise weiter, bis ein nicht-grafisches Zeichen gefunden wird. Ansonsten würde der nächste Leseversuch an den gleichen Zeichen scheitern, die auch schon beim vorherigen Versuch zum Scheitern geführt haben.Wenn ich recht darüber nachdenke, wäre
for (char c = in.peek(); in && !isspace(c); c = in.peek())besser, weil dies besser zu dem passt, was
operator>>macht.
-
Ich hab keine Ahnung was SeppJ da macht, aber eigentlich nimmt man den Klassiker
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );(Nur mal so kontextfrei, ich hab die Unterhaltung nicht verfolgt, vielleicht brauchst du seine Version)
Es gibt keine if-Schleifen.
Noch nicht

-
SeppJ schrieb:
Leider hast du so ziemlich alles falsch verstanden.
DerNoob1993 schrieb:
Ich habe denke ich verstanden wie das ganze funktioniert.
Als erstes wenn das cin fehlschlägt benutzt man die cin.clear() Funktion um soweit ich richtig verstanden habe den Eingabebuffer zu leeren.Es gibt keinen Eingabepuffer.
Als nächstes übergibt man den stream an die selbst geschriebene Funktion welche jedes Zeichen des Streams von Anfang bis Ende ignoriert(löscht?).
Es gibt keinen Anfang. Hier wird auch nicht bis Ende gelöscht. Man weiß normalerweise nicht einmal, ob es ein Ende gibt oder wann es kommt.
Dadurch kann man es danach auch wieder neu einlesen ,und die if schleife wird nicht endlos ausgeführt.
Es gibt keine if-Schleifen.
Noch einmal:
Es wird gelesen. Es wird geprüft, ob das Lesen erfolgreich war. Falls dies der Fall war: Fertig. falls das Lesen nicht erfolgreich war: Dann befindet sich der Stream in einem Fehlerstatus (das ist quasi die Definition von nicht erfolgreichem Lesen). Dieser wird mit clear aufgehoben. Damit signalisiert man dem Stream, dass man den Fehler erkannt hat und sich darum kümmern wird. Dann wird die selbstgeschriebene Funktion aufgerufen. Diese setzt den Stream so lange zeichenweise weiter, bis ein nicht-grafisches Zeichen gefunden wird. Ansonsten würde der nächste Leseversuch an den gleichen Zeichen scheitern, die auch schon beim vorherigen Versuch zum Scheitern geführt haben.Wenn ich recht darüber nachdenke, wäre
for (char c = in.peek(); in && !isspace(c); c = in.peek())besser, weil dies besser zu dem passt, was
operator>>macht.Danke das war verständlicher für mich.
Die Funktionen waren für mich noch zum Teil unbekannt ,aber nach deiner jetzigen Erklärung habe ich verstanden ,was die einzelnen Funktionen genau machen ,und wie das ganze zusammenhängt. Habe mir die Funktionen nur ergoogelt gehabt , und nicht genau verstanden gehabt wie das ganze zusammenhängt.Edit : Ja If Schleifen

Naja bin halt noch Anfänger und bringe manche Fachbegriffe noch durcheinander obwohl das jetzt auch für mich schon ein ziemlicher Fail war
.
-
Nexus schrieb:
HarteWare schrieb:
Sind Aufzählungstypen gleichbedeutend mit Charakteren, also "char" ?
Nein. Aufzählungstypen sind
enums.Dann bin ich jetzt aber leicht verwirrt... Man kann mit switch() nämlich auch chars abgleichen. Fallen diese etwa in die Kategorie "integrale Werte"?
mfg
-
Dann bin ich jetzt aber leicht verwirrt... Man kann mit switch() nämlich auch chars abgleichen. Fallen diese etwa in die Kategorie "integrale Werte"?
Darunter fallen
bool,char,char16_t,char32_t,wchar_t,short,int,long, undlong long.
P.S.: Nicht "Werte". Typen.
-
Sone schrieb:
Darunter fallen
bool,char,char16_t,char32_t,wchar_t,short,int,long, undlong long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.
-
fifi ftfy schrieb:
Sone schrieb:
Darunter fallen
bool,char,char16_t,char32_t,wchar_t,short,int,long, undlong long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned/plain char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.
-
out schrieb:
fifi ftfy schrieb:
Sone schrieb:
Darunter fallen
bool,char,char16_t,char32_t,wchar_t,short,int,long, undlong long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned/plain char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned/plain char,wchar_t,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long, inklusive sämtlicher cv Varianten.
-
fifi ftfy schrieb:
Sone schrieb:
Darunter fallen
bool,char,char16_t,char32_t,wchar_t,short,int,long, undlong long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.Ich habe absichtlich die Vorzeichenbehaftung weggelassen. Weil sie hier irrelevant ist (eig. genauso irrelevant wie bspw.
char32_t, aber was solls
)Das es separate Typen sind, ist mir aber schon klar, ne?
inklusive sämtlicher cv Varianten.
Na, weil ihr beiden es doch so drauf anlegt, zähl die doch mal alle auf, ich bin sicher wir haben was davon

-
bool
const bool
volatile bool
const volatile bool
signed char16_t
const signed char16_t
volatile signed char16_t
const volatile signed char16_t
unsigned char16_t
const unsigned char16_t
volatile unsigned char16_t
const volatile unsigned char16_t
signed char32_t
const signed char32_t
volatile signed char32_t
const volatile signed char32_t
unsigned char32_t
const unsigned char32_t
volatile unsigned char32_t
const volatile unsigned char32_t
signed char
const signed char
volatile signed char
const volatile signed char
unsigned char
const unsigned char
volatile unsigned char
const volatile unsigned char
signed wchar_t
const signed wchar_t
volatile signed wchar_t
const volatile signed wchar_t
unsigned wchar_t
const unsigned wchar_t
volatile unsigned wchar_t
const volatile unsigned wchar_t
signed short
const signed short
volatile signed short
const volatile signed short
unsigned short
const unsigned short
volatile unsigned short
const volatile unsigned short
signed int
const signed int
volatile signed int
const volatile signed int
unsigned int
const unsigned int
volatile unsigned int
const volatile unsigned int
signed long
const signed long
volatile signed long
const volatile signed long
unsigned long
const unsigned long
volatile unsigned long
const volatile unsigned long
signed long long
const signed long long
volatile signed long long
const volatile signed long long
unsigned long long
const unsigned long long
volatile unsigned long long
const volatile unsigned long long
-
unsigned bool? signed bool?
gibts das echt?
-
upps, mein fehler.
-
Wofür steht nochmal volatile?
0x0ERROR
-
0x0ERROR schrieb:
Wofür steht nochmal volatile?
0x0ERROR
N3337 [dcl.type.cv]/7
volatile is a hint to the implementation to avoid aggressive optimization involving the object
because the value of the object might be changed by means undetectable by an implementation. See 1.9 for
detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are
in C.Es kann allerdings wegen as-if ignoriert werden.
-
out schrieb:
fifi ftfy schrieb:
Sone schrieb:
Darunter fallen
bool,char,char16_t,char32_t,wchar_t,short,int,long, undlong long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.Darunter fallen
bool,char16_t,char32_t,signed/unsigned/plain char,signed/unsigned short,signed/unsigned int,signed/unsigned longundsigned/unsigned long long.plain char ist entweder ein typedef auf signed oder auf unsigned char, deshalb fällt der weg. Gleich wie wchar_t.
cv-Qualifiers gehören nicht wirklich zum Typ. Die kriegt man mit std::decay weg. Ernsthaft. Ist schon fast ein Getrolle was Nathan da liefert.
-
plain char ist entweder ein typedef auf signed oder auf unsigned char, deshalb fällt der weg.
Blödsinn. Es ist kein
typedefdarauf, 's stimmt schon dass es sich wie eines der beiden verhält. Aber es sind drei verschiedene Typen, egal was du machst.
Edit: Nicht so vehement.
-
fifi ftfy schrieb:
cv-Qualifiers gehören nicht wirklich zum Typ. Die kriegt man mit std::decay weg. Ernsthaft. Ist schon fast ein Getrolle was Nathan da liefert.
Wieso?
Weil einmal wchar_t mit drin war und einmal nicht, habe ich hier nachgeguckt. Dann habe ich das auch so hingeschrieben und sone wollte, dass ich das alles aufschreibe.
-
Gäb's das Wort Nervensäge noch nicht, würde es wohl Sone heißen.
2764 posts seitdem du deinen nick geändert hast? WTF?
-
Nathan schrieb:
sone wollte, dass ich das alles aufschreibe.
Das war ironisch gemeint, und ich wollte nie dass du das machst...

@EOP: sigh, was passt dir nicht?