Überlauf beim Char-Array
-
TiSie schrieb:
Leider funktioniert das nicht so richtig. Bei einer Eingabe über 20 Zeichen wird eine andere Fehlermeldung aus einem ganz anderen Programmteil ausgegeben und das Programm endet nicht von selbst. Hab ich einen logischen oder syntaktischen Fehler drin? Gibts es vllt. Alternativen, die wesentlich eleganter sind?
Wenn man in deinem geposteten Codeschnipsel die fehlenden Semikolons hinzufügt und alles in eine main Funktion einfügt, funktioniert das Programm und tut auch das was du erwartest. Der Fehler liegt daher vermutlich nicht innerhalb der geposteten Zeilen.
-
Hier nochmal den Code-Schnipsel als eigenes Programm (und fehlende Semikolons ergänzt). Funktioniert leider immer noch nicht. Liegt es vllt an der Entwicklungsumgebung? Arbeite mit Dev-C++
#include <iostream> using namespace std; main(){ char wandelZahl[21]; // Eingabe einlesen cin.getline(wandelZahl,21); // Tastaturpuffer leeren, falls Eingabe > 20 Zeichen: if((cin.rdbuf()->in_avail())>1){ cin.clear(); // Falls Fehlerbit gesetzt wird!? sinnvoll? cin.ignore(cin.rdbuf()->in_avail()); cout << "Eingabe ist länger als 20 Zeichen!"; system("pause"); return 0; } }
-
Wie wär's, wenn du mal Fehlermeldung und -position im Code postest?
-
Das merkwürdige ist, dass keine Fehlermeldung erscheint. Die Compilation und Ausführung des Programms erfolgt ohne Probleme.
Bei der anschließenden Eingabe von weniger als 21 Zeichen wird nichts ausgegeben, was ja auch logisch ist, weil die Bedingung der if-Selektion nicht erfüllt ist.
Bei der Eingabe von gleich oder mehr als 21 Zeichen müsste dann jedoch die Eintrittsbedingung erfüllt sein und "Eingabe ist länger als 20 Zeichen!" ausgegeben werden. Dies wird aber aus mir unerklärlichen Gründen nicht gemacht.
-
in_avail() ist in der Regel immer 0.
-
ich dachte cin.rdbuf()->in_avail() gibt mir die Anzahl Zeichen wieder, die sich noch im Lesepuffer befinden?
-
So sollte es funktionieren...
if (!(cin.getline(wandelZahl,21))) { cout << "Eingabe ist länger als 20 Zeichen!"; }Gruss,
arb3r
-
TiSie schrieb:
ich dachte cin.rdbuf()->in_avail() gibt mir die Anzahl Zeichen wieder, die sich noch im Lesepuffer befinden?
Ja, im Lesepuffer des C++-Streams. Die Zeichen könnten sich aber noch im Puffer des Betriebssystems befinden und erst beim nächsten Leseaufruf in den Puffer des Streams übertragen werden.
Ergo ist die Aussagekraft von in_avail, wie SeppJ schon sagte, in diesem Fall ziemlich wertlos.
-
ah okay, die direkte Boolesche Abfrage ist natürlich elegant. Danke dafür. Damit läuft das Programm. Hab aber noch zwei Fragen:
1. Wann ist !(cin.getline(wandelZahl,21)=true ?? Wirklich nur bei Bereichsüberschreitung des Arrays?
2. Wie kann ich die restlichen im Lesepuffer verbliebenen Zeichen löschen? Erst Fehlerbit mit cin.clear() löschen und dann?
-
TiSie schrieb:
Liegt es vllt an der Entwicklungsumgebung? Arbeite mit Dev-C++
Schau zu DEV-C++ mal ins Compiler/IDE-Forum weiter unten. Das Ding ist veraltet.
-
main hat einen Rückgabetyp. Wenn dein Compiler das ohne schluckt, solltest du ihn schleunigst wechseln.
-
system("pause") ist so eine Sache. Schau mal in die FAQ bzgl. "Fenster schließt sich" etc, da gibts Alternativen, die dazu auch noch portabel sind. (Oder starte dein Programm einfach aus der Konsole)
!(cin.getline(wandelZahl,21)=true
getline gibt eine Referenz auf das Streamobjekt zurück. Der Ausdruck (wenn man ihn um die fehlende Klammer ersetzt) gibt true, wenn cin nach getline false ergibt. genauer, wenn irgendwas schief gelaufen ist. Was da bei getline schief laufen kann, sagt dir eine Referenz.
Wie kann ich die restlichen im Lesepuffer verbliebenen Zeichen löschen? Erst Fehlerbit mit cin.clear() löschen und dann?
wie gehabt mit ignore. Als parameter wird gerne []std::numeric_limits<unsigned>::max()[/c] übergeben.
-
-
Ob die IDE DEV besser geworden ist weiss ich nicht.
Die Compiler ist aktueller.Hier der Link:
http://orwellengine.blogspot.com/2011_09_01_archive.htmlAktuelle Version DEV-C++ 5.0.0.3 mit Datum 2011.sep.08
MfG f.-th.
-
pumuckl schrieb:
- main hat einen Rückgabetyp. Wenn dein Compiler das ohne schluckt, solltest du ihn schleunigst wechseln.
Sollte er nicht deswegen, da sowohl im Sprachstandard C++ wie auch bei C99 ein implizites "return 0" spezifiziert ist bei Fehlen einer expliziten Angabe.
Über Sinn und Unsinn dieses "Features" im Standard kann man sicher geteilter Meinung sein.
-
Wutz schrieb:
Sollte er nicht deswegen, da sowohl im Sprachstandard C++ wie auch bei C99 ein implizites "return 0" spezifiziert ist bei Fehlen einer expliziten Angabe.
Über Sinn und Unsinn dieses "Features" im Standard kann man sicher geteilter Meinung sein.pumuckl schrieb:
- main hat einen Rückgabetyp.
TiSie schrieb:
#include <iostream> using namespace std; main(){
-
TiSie schrieb:
Hier nochmal den Code-Schnipsel als eigenes Programm (und fehlende Semikolons ergänzt). Funktioniert leider immer noch nicht. Liegt es vllt an der Entwicklungsumgebung? Arbeite mit Dev-C++
Das scheint tatsächlich am Compiler zu liegen. Ich nehme an du arbeitest mit diesem frei erhältlichen gcc Ding. Und die interpretieren den Standard so, dass sie get_avil() bzw. showmanyc() einfach immer 0 zurückgeben lassen. Mit den Compilern von Microsoft funktioniert dein Ansatz.
D.h. du musst umdenken und es anders versuchen.
-
pumuckl schrieb:
TiSie schrieb:
Liegt es vllt an der Entwicklungsumgebung? Arbeite mit Dev-C++
Schau zu DEV-C++ mal ins Compiler/IDE-Forum weiter unten. Das Ding ist veraltet.
-
main hat einen Rückgabetyp. Wenn dein Compiler das ohne schluckt, solltest du ihn schleunigst wechseln.
-
system("pause") ist so eine Sache. Schau mal in die FAQ bzgl. "Fenster schließt sich" etc, da gibts Alternativen, die dazu auch noch portabel sind. (Oder starte dein Programm einfach aus der Konsole)
!(cin.getline(wandelZahl,21)=true
getline gibt eine Referenz auf das Streamobjekt zurück. Der Ausdruck (wenn man ihn um die fehlende Klammer ersetzt) gibt true, wenn cin nach getline false ergibt. genauer, wenn irgendwas schief gelaufen ist. Was da bei getline schief laufen kann, sagt dir eine Referenz.
Wie kann ich die restlichen im Lesepuffer verbliebenen Zeichen löschen? Erst Fehlerbit mit cin.clear() löschen und dann?
wie gehabt mit ignore. Als parameter wird gerne []std::numeric_limits<unsigned>::max()[/c] übergeben.
Alles klar! Jetzt läuft es wunderbar!

Ich glaub bei der nächsten gelegenheit sollte ich mir mal den Microsoft-Compiler zulegen.
Vielen Dank euch Allen für die wirklich konstruktive Hilfe!
-