[Novize] Wieso landet /n nicht im Puffer bei Integer?
-
Falke88 schrieb:
Von der Lösung habe ich auch gelesen. ist dies aber nicht eigentlich eine "unsaubere" Lösung?
Sauberer geht's kaum. Du möchtest ein non-Whitespace Zeichen lesen. Der gezeigte Formatstring beschreibt exakt diese Anforderung.
-
c weakness schrieb:
scanf belässt zeichen, die nicht zum formatstring gehören, im eingabestrom.
Das ist eine unzulässige Verkürzung der Standardvorgaben.
Wenn überhaupt dann: scanf belässt endende zeichen, die nicht zum formatstring "gehören", im eingabestrom. Außer bei %c,%[],%n überliest scanf nämlich führende (Whitespace)Zeichen immer, belässt also nicht immer nicht passende Zeichen im Eingabepuffer.
-
SeppJ schrieb:
Falke88 schrieb:
Von der Lösung habe ich auch gelesen. ist dies aber nicht eigentlich eine "unsaubere" Lösung?
Sauberer geht's kaum. Du möchtest ein non-Whitespace Zeichen lesen. Der gezeigte Formatstring beschreibt exakt diese Anforderung.
Nein, das ist so auch nicht richtig. Wenn in der o.g. Anwendung der Anwender beim vorigen scanf"%d" ein nicht zu "%d" passendes Zeichen ungleich Whitespace eingibt, reicht ein folgendes " %c" nicht aus.
Die simple Eingabe von 123a statt 123 würde also das Programm schon scheitern lassen.
Eine saubere Lösung sieht also so aus, nach jedem scanf die hier schon 1000x genannte Variante zum Löschen aller vorhandenen Zeichen aus stdin zu verwenden, also z.B.{ int c; while( (c=getchar())!='\n' && c!=EOF ); }
Es heißt auch nicht /n sondern \n, und nicht ANCII sondern ASCII.
-
Wutz schrieb:
Wenn in der o.g. Anwendung der Anwender beim vorigen scanf"%d" ein nicht zu "%d" passendes Zeichen ungleich Whitespace eingibt, reicht ein folgendes " %c" nicht aus.
Die simple Eingabe von 123a statt 123 würde also das Programm schon scheitern lassen.Das würde das a einlesen, so wie ich es erwarten und als Anwender wünschen würde.
-
Wie sinnvoll wäre ein zuvor eingegebenes 'a' als Antwort auf die folgende Frage
printf("Mit Anhaenger oder ohne? (y/n) ");
Sicher wohl ziemlich sinnfrei.
Das "Verschieben" der Eingabepufferbereinigung bei einem scanf auf das nächste scanf trägt auch nicht gerade zur Übersichtlichkeit bei. Jedes scanf sollte sich um seine eigenen Hinterlassenschaften kümmern und sich nicht auf andere verlassen.
-
Falke88 schrieb:
char* Anhaenger[1]; scanf("%c",&Anhaenger);
Ich hab schon viel Konfusion um Zeichen, Strings und String-Arrays gesehen, aber diese Kombination ist mir neu.
Meintest du
char Anhaenger;
?
-
Wutz schrieb:
Das "Verschieben" der Eingabepufferbereinigung bei einem scanf auf das nächste scanf trägt auch nicht gerade zur Übersichtlichkeit bei. Jedes scanf sollte sich um seine eigenen Hinterlassenschaften kümmern und sich nicht auf andere verlassen.
Das dumme ist, dass es keinen Eingabepuffer gibt und sobald du von simplen Konsolenprogrammen wegkommst, bricht dein ganzes Modell zusammen. Wenn du ein zeilenbasiertes Eingabeformat vorschlagen möchtest, dann ist das natürlich auch eine gute Methode, aber dann lies auch bitte ganze Zeilen ein, anstatt mit scanf auf dem Eingabestrom zu hantieren. Die Zeile darfst du danach gerne mit sscanf auseinander nehmen.
-
Das Problem sind doch nur die Anwender.
Wenn die immer nur korrekte Eingaben machen würden, wäre das programmieren so einfach.
-
seldon schrieb:
Falke88 schrieb:
char* Anhaenger[1]; scanf("%c",&Anhaenger);
Ich hab schon viel Konfusion um Zeichen, Strings und String-Arrays gesehen, aber diese Kombination ist mir neu.
Meintest du
char Anhaenger;
?
hahaha ja das meinte ich, habe ich auch geändert - das war halt mein letzterer Stand um dem Problem selber auf den Grund zu gehen, bevor ich bemerkt habe das es wohl am \n Newline gelegen hat
-
Das nur auf fehlerhafte Eingabe zu reduzieren trifft nicht den Kern des Problems.
Da das Problem hier im Forum und in anderen Foren viele Beiträge produziert hat,ist das auch relevant.
Lösungsvorschläge wurden schon einige erwähnt. Aber da keiner der Lösungsvorschläge seinen Weg in den C-Standard gefunden hat, hat wohl jede der Ideen ein Handicap.
Ich mache C nur ein wenig um meine grauen Zellen zu beschäftigen, deshalb muss folgendes nicht zutreffen:
Zu DOS-Zeiten mit DOS-C-Compilern ist mir dieses Problem nicht bekannt. Wenn ich alte C-Quelltexte, die unter DOS mit mehreren Compilern übersetzt nicht auffällig waren, heute mit modernen C-Compilern unter Windows übersetzte, habe ich plötzlich dieses Problem.Meine Vermutung:
Zu DOS-Zeiten war der Weg vom Programm zur CPU sehr kurz. Das musste so sein damit man halbwegs zügig arbeiten konnte. Deshalb war das Problem, ich nenn es mal so, "Eingabepuffer" kein Problem.Also Weg der Daten damals: Programm -> Register der Hardware.
Heute bei den Windows ab WIN2000 spielt ja das Betriebssystem eine wesentliche Rolle. Dieses versucht direkte Zugriffe der Programme auf die Hardware nur auf zulässige Aktionen zu beschränken. Da Windows ja prüft ob das Programm sauber arbeitet und die Eingaben sich im grünen "Bereich" befinden, ist da wahrscheinlich das Problem entstanden.
Weg unter Windows 2000 und neuer: Programm -> Betriebssystem ( eventuell gar in mehreren "Sicherheitsstufen" ) -> und, wenn das Betriebssystem zufrieden ist übergibt es die Daten an die Hardwareregister.
Wenn man mal schaut in der MSDN, was Microsoft von der "alten C-Sprache" mit sollte man nicht mehr verwenden gekennzeichnet hat ist die Liste ja schon länger.
Zur Dateneingabe als Beispiel:
gets - okay das sollte man wirklich nicht mehr nutzen
aber auch von scanf wird abgeraten und auf den Microsoft-C-Sonderweg verwiesen.C99 wurde ja von Microsoft weitgehend ignoriert. Der C11-Standard übernimmt aber einige Teile des Mircosoft-C-Weges.
Vielleicht haben wir ja Glück, das der nächste C-Standard da mehr Klarheit bringt.