Weltraumvernichtungssimulator
-
Habs ungefähr verstanden, aber hab mir trotzdem mal ein "cin" Tut angeschaut. In diesem hab ich gelernt, dass es bei "cin" einen unsichtbaren Buffer gibt. Und wenn man z.B. "cin >> answer;" macht dann wird alles gleich aus dem unsichtbaren Buffer in die Variable answer geschrieben. Stimmts soweit?
Und wenn man nur "cin.get()" macht, dann wirds nur in den Buffer geschrieben. Und jetzt weiß ich nicht so genau wie man sich das Zeug aus dem Buffer anschaut. Ich glaub das geht so:#include <iostream> using namespace std; int main() { cin.get(); cout << cin.get() << endl; return 0; }Da stehen jetzt aber nur komische Sachen drin. Bei der Eingabe von 1000 --> 48;
Eingabe von 1-9 --> 10; Eingabe von 30 u. 40 --> 48; Eingabe von 11 --> 49;...
bei Bcuhstaben: Bei einzelnen Bcuhstaben immer 10; Bei mehr als zwei Buchstaben --> unterschiedliche Sachen.Was genau passiert hier? Und wie kann ich aus dem Buffer nun den Inhalt bekommen?
MfG
Stromberg.
-
http://www.cplusplus.com/reference/iostream/istream/get.html
Lies dir doch einfach mal die Referenz dazu durch.
-
Mh, ich verstehe jetzt den Code, verstehe aber nicht warum man das macht.
while (!(std::cin >> answer) || answer < 1 || answer > 3) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); }Warum löscht man Zeichen für Zeichen den Buffer bis er leer ist? Bei "std::cin >> answer" wird der Speicher doch automatisch in "answer" geleert. Also würde es ja reichen einfach das "cin" zu wiederholen wenn die Anweisung zutrifft "(std::cin >> answer) || answer < 1 || answer > 3)"...? Und bei nem neuen "cin" Aufruf is der Buffer ja wieder leer, weil ja alles in "answer" steht.
MfG
Stromberg
-
Hab vorhin noch was im Internet gelesen, das wenn man "numeric_limits" verwendet man die library <limits> einbinden muss? Stimmt das?
MfG
Stromberg
-
Stromberg schrieb:
Hab vorhin noch was im Internet gelesen, das wenn man "numeric_limits" verwendet man die library <limits> einbinden muss? Stimmt das?
MfG
Strombergja und das ist ein Standardheader.
-
Weiß niemand warum man die einzelnen Zeichen jetzt löscht? (meine vorletzte Frage)
MfG
Stromberg
-
Probier das mal aus...
int main() { string answer; cin >> answer; // Hallo du als Eingabe cout << answer; // Einmal mit std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); cin >> answer; cout << answer; // Einmal ohne cin >> answer; //Hallo du als Eingabe cout << answer; cin >> answer; cout << answer; return 0; }Wie du nach diesem Beispiel siehst, steht zwar alles im Buffer, nach answer wird aber nur bis zum ersten Leerzeichen geschrieben...
Gruß
sonic
-
Also paar Frage:
1. Wenn ich nur die Zeile mit dem "clear" und "ignore" mache, dann wird ja auch eine "cin Eingabe" aufgerufen? Wer ruft das bitte auf?#include <iostream> #include <string> using namespace std; int main() { string answer; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); return 0; }2.Bei dem Beispiel, also da verstehe ich gar nicht was passiert. [ich hab bei cout noch n endl hinzugefügt, das es übersichtlicher wird]
#include <iostream> #include <string> using namespace std; int main() { string answer; cin >> answer; // Hallo du als Eingabe cout << answer << endl; // Einmal mit std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); cin >> answer; cout << answer << endl; // Einmal ohne cin >> answer; //Hallo du als Eingabe cout << answer << endl; cin >> answer; cout << answer << endl; return 0; }AUSGABE:
Hallo Werner // <-- EINGABE 1
Hallo //<-- AUSGABE 1
Hallo Werner // <-- EINGABE 2
Hallo // <-- AUSGABE 2
Werner // <-- AUSGABE 2
Hallo Werner // <-- EINGABE 3
Hallo // <-- AUSGABE 3Also bei der ersten Eingabe verstehe ichs, des is ja so standard, des kenn ich schon von früher, wenn man bei "cin" ganze Sätze mit Leerzeichen eingibt...dann kommt nur alles bis zum ersten Leerzeichen. Warum eigentlich, reagiert "cin" nicht nur auf "\n" sondern auch auf " "? Aber um das zu verhindern kann man ja einfach "cin.get()" verwenden?
#include <iostream> #include <string> using namespace std; int main() { string answer; char a; cin.get(a); do { answer +=a; a=cin.get(); }while(a!='\n'); cout << answer << "\n"; return 0; }3. Bei der zweiten Ausgabe wird nun doch auch das nach dem Leerzeichen ausgegeben. Das liegt jetzt wohl irgendwie an dem "clear(...)" und an dem "ignor(...)". Aber was genau passiert da? Da wird halt das "clear" aufgerufen das alle Errors zurücksetzt, und das "ignore", das alle Zeichen im Buffer bis zu "\n" löscht, und wenns kein "\n" gibt, dann löscht er die maximale Anzahl an Zeichen die man in den Buffer reinschreiben kann? (4 Byte?)
Und warum wird bei der Ausgabe 2 nicht alles in eine Zeile geschriebn, sondern in zwei?MfG
Stromberg
-
#include <iostream> #include <string> #include <limits> int main() { std::string answer; // Default-Konstruktor von std::string aufrufen std::cin.clear(); // std::cin fehlerflags rauswerfen std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // nen bissel kram aus std::cin-buffer rauswerfen(wobei das hier keinen Sinn hat, da der Buffer noch leer ist -.-) std::cin.get(); // Warte auf eine Taste, bevor du das Programm schließt. }sollte in answer eigentlich nur "" stehen
Demnach: Leer!#include <iostream> #include <string> #include <limits> int main() { std::cout << ">===== Teil 1 =====<" << std::endl; std::string answer; std::cin >> answer; // Eingabe: "Hallo, Mustermann\n"; answer: "Hallo," std::cout << answer << std::endl; // Ausgabe: "Hallo,\n" // std::cin-Buffer: "Mustermann\n" std::cin.clear(); // kein Fehlerbit gestetzt, aber trotzdem zur sicherheit aufrufen... std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // "Mustermann\n" rauswerfen. std::cout << ">===== Teil 2 =====<" << std::endl; std::cin >> answer; // Eingabe: "Hallo, Mustermann\n"; answer: "Hallo," // std::cin-Buffer: "Mustermann\n" std::cout << answer << std::endl; // Ausgabe: "Hallo," std::cin >> answer; // Eingabe: "Hallo, Mustermann\n"; answer: "Mustermann" // std::cin-Buffer: "Hallo, Mustermann\n" std::cout << answer << std::endl; // Ausgabe: "Mustermann\n" std::cin >> answer; // Eingabe: "Hallo, Mustermann\n"; answer: "Hallo," std::cout << answer << std::endl; }guck dir immer die Kommentare an ... es bleibt halt immer der Rest im Buffer stehen ...
Aber um das zu verhindern kann man ja einfach "cin.get()" verwenden?
Nein. Man nutzt dafür std::getline (#include <string>). Ließt bis zum nächsten std::endl ein. Wobei der 1. Parameter die std::istream-Referenz ist und der 2. der Ziel std::string.
#include <iostream> #include <string> int main() { std::cout << "Antwort: " << std::flush; std::string answer; std::getline(std::cin, answer); std::cout << "=> " << (answer == "Das Passwort" ? "richtig" : "falsch" << std::endl; }...
Hoffe das hilft dir weiter
Ist aber jetzt wieder mal stark vereinfacht erklärt ...
-
Ah, okay jetzt hab ich endlich mal den sinn davon verstanden. Wenn irgend n Dödel z.B. "3324 45345" eingibt, dann würde immer ein Rest im Buffer stehen, und der wäre dann beim nächsten "cin" dabei, und dann würds wieder nicht gehen......
So aber noch die andere Frage, ich verstehe nicht warum hier ein "cin", also in der Konsole so eine Eingabeaufforderung aufgerufen wird:
#include <iostream> #include <limits> int main() { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); }???
Und was ich auch nicht ganz verstehe, warum hast du bei dem letzten Beispiel "std::flush" verwndet, das nutzt man doch glaub wenn man den Computer zwingen will alles sofort aus dem zwischen buffer von "cout" auf den Bildschirm zu schreiben. Aber in was für Fällen genau wendet man das an? War das jetzt in deinem Fall wichtig, weil ich wäre da nie draufgekommen das jetzt zu verwenden.
MfG
Stromberg
-
Noch was, ich wollte das jetzt so ganz professionel machen, und hab mein Code so in verschiedene Headers unterteilt. (Modulare Programmierung?)
Ich hab eine "game.hpp" mit der Deklaration der Klasse "game" und eine "game.cpp" mit der Definition der Klasse "game". Bist jetzt müsste noch alles stimmen. So, dann wollte ich noch eine Header Datei namens "Operators.hpp" machen mit der Deklaration der Operatoren (hab bis jetzt zwar erst einen überladen, aber vll. werdens ja noch mehr). Und einen namens "Operators.cpp" mit der Defintion der Operatoren. Ist das sinnvoll und übersichtlicher wenn ich die Operatoren auch noch in einen Header stecke, oder eher unsinn? Hier mal die 4 Errors:-------------- Build: Debug in GAME --------------- Compiling: operators.cpp In file included from operators.cpp:1: operators.hpp:4: error: expected constructor, destructor, or type conversion before '&' token operators.hpp:4: error: expected `,' or `;' before '&' token operators.cpp:3: error: expected constructor, destructor, or type conversion before '&' token operators.cpp:3: error: expected `,' or `;' before '&' token Process terminated with status 1 (0 minutes, 0 seconds) 4 errors, 0 warningsAm Code kanns nicht liegen, weil der ging vorhin noch, als alles in einer Datei war.
Hier der Code:main.cpp
#include "game.hpp" #include "operators.hpp" using namespace std; int main() { game wus; wus.new_story(game::part("Wer wollen sie sein?\n", "1. Hitler\n","2. Gahndi\n","3. Georg W. Bush\n", "Sie sind nun Hitler!\n", "Sie sind nun Gahndi!\n", "Sie sind nun Georg W. Bush!\n")); wus.set_story(0); return 0; }game.hpp
#ifndef INCLUDE_GAME_HPP #define INCLUDE_GAME_HPP #include <vector> #include <string> #include <limits> class game { public: game(); ~game(); struct part { std::string m_question, m_a, m_b, m_c, m_effect[3]; part(const std::string& question_,const std::string& a_,const std::string& b_,const std::string& c_, const std::string& effect1_,const std::string& effect2_,const std::string& effect3_); }; inline void new_story(const part& data) {m_story.push_back(data);} void set_story(size_t index); friend std::ostream& operator<< (std::ostream& out, const game::part& data); private: std::vector<part> m_story; const std::string message; }; #endif // GAME_HPP_INCLUDEDgame.cpp
#include <iostream> #include "game.hpp" game::game() :message("Du bist doch Deutschlands d\x81mmster! Ist es so schwierig eine Zahl zwischen\n1 und 3 einzugeben?" + std::string(" Probiers nochmal du Arschloch!\n")) { } game::~game() { } game::part::part(const std::string& question_,const std::string& a_,const std::string& b_,const std::string& c_, const std::string& effect1_,const std::string& effect2_="",const std::string& effect3_="") :m_question(question_),m_a(a_),m_b(b_),m_c(c_) { m_effect[0]=effect1_; m_effect[1]=effect2_; m_effect[2]=effect3_; } void game::set_story(size_t index) { std::cout << m_story[index]; unsigned short save; while(!(std::cin >> save) || (save>3) || (save<1)) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::cout << message; } if (m_story[index].m_effect[1].empty() == true && m_story[index].m_effect[2].empty() == true) { std::cout << m_story[index].m_effect[0]; return; } std::cout << m_story[index].m_effect[save-1]; }operators.hpp
#ifndef OPERATORS_HPP_INCLUDED #define OPERATORS_HPP_INCLUDED std::ostream& operator<< (std::ostream& out, const game::part& data); #endif // OPERATORS_HPP_INCLUDEDoperators.cpp
#include "operators.hpp" std::ostream& operator<< (std::ostream& out, const game::part& data) { out << data.m_question << data.m_a << data.m_b << data.m_c; return out; }MfG
Stromberg
-
du musst noch innerhalb von operators.hpp #include <iostream> am anfang einfügen. Bislang hast du das nur in der game.cpp stehen. Das Problem ist, dass der Compiler jede übersetzungseinheit(=cpp datei) einzeln betrachtet, in der main.cpp gelten also die deklarationen von game.cpp nicht.
oder einfacher ausgedrückt:
#ifndef OPERATORS_HPP_INCLUDED #define OPERATORS_HPP_INCLUDED std::ostream& operator<< (std::ostream& out, const game::part& data);wenn das der anfang deines projektes wäre, woher sollte der compiler wissen, was std::ostream ist?
-
Ach so, mh ich hab immer gedacht wenn irgendwo im Code die include Datei vorkommt dann würde diese gleich für alle gelten?
Na ja zumindestens hab ich jetzt <iostream> und auch noch "game.hpp" eingefügt.
Ich hab immer gedacht das wäre schlechter Stil wenn man überal die gleichen include Datein hat....na ja wieder was gelernt.#ifndef OPERATORS_HPP_INCLUDED #define OPERATORS_HPP_INCLUDED #include <iostream> #include "game.hpp" std::ostream& operator<< (std::ostream& out, const game::part& data); #endif // OPERATORS_HPP_INCLUDEDMfG
StrombergZUSATZ:
Jetzt ist meine vorletzte Frage leider auf Seite 4 verschuwnden:gerichtet @ (D)Evil, oder jemand der halt auch weiß um was es geht.
Ah, okay jetzt hab ich endlich mal den sinn davon verstanden. Wenn irgend n Dödel z.B. "3324 45345" eingibt, dann würde immer ein Rest im Buffer stehen, und der wäre dann beim nächsten "cin" dabei, und dann würds wieder nicht gehen......
So aber noch die andere Frage, ich verstehe nicht warum hier ein "cin", also in der Konsole so eine Eingabeaufforderung aufgerufen wird:
#include <iostream> #include <limits> int main() { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); }???
Und was ich auch nicht ganz verstehe, warum hast du bei dem letzten Beispiel "std::flush" verwndet, das nutzt man doch glaub wenn man den Computer zwingen will alles sofort aus dem zwischen buffer von "cout" auf den Bildschirm zu schreiben. Aber in was für Fällen genau wendet man das an? War das jetzt in deinem Fall wichtig, weil ich wäre da nie draufgekommen das jetzt zu verwenden.
MfG
Stromberg
-
Und was ich auch nicht ganz verstehe, warum hast du bei dem letzten Beispiel "std::flush" verwendet, das nutzt man doch glaub wenn man den Computer zwingen will alles sofort aus dem zwischen Buffer von "cout" auf den Bildschirm zu schreiben. Aber in was für Fällen genau wendet man das an? War das jetzt in deinem Fall wichtig, weil ich wäre da nie drauf gekommen das jetzt zu verwenden.
Ehm std::flush bewirkt nur das der Inhalt des Ausgabe-Buffers auf das Ausgabemedium übertragen wird und der Buffer danach leer zurückbleibt.
In diesem Fall ist es noch nicht einmal nötig, das std::cin schon dafür sorgt, das std::cout geflusht wird. Gibt spezielle Fälle, wo man sowas braucht.
Aja und ein std::endl ist nichts anderes als ein "\n" an den Ausgabe-Buffer anhängen und dann std::flush aufrufen!#include <iostream> #include <limits> int main() { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); }sollte egentlich keine Eingabe erwarten ... ist zumindest keine der Funktionen für vorgesehen

-
Aber warum wird bei mir dann eine Eingabeaufforderung in der Konsole aufgerufen? mh? Also ich mein jetzt halt so nen blickenden strich "_" schon klar^^?
http://www.bilder-speicher.de/07090801649295.gratis-foto-hosting-page.htmlMfG
Stromberg
-
oO normal sollte sich die Eingabeaufforderung sofort wieder schließen, da dein Programm eigentlich sofort am Ende sein müsste -.- Was fürn Compiler?
-
Compiler ist MinGW. IDE ist Code::blocks, wie man auf dem Bild unschwer erkennen kann
(aber was für eine IDE es ist, is glaub unwichtig?)MfG
Stromberg
-
Stromberg schrieb:
Compiler ist MinGW. IDE ist Code::blocks, wie man auf dem Bild unschwer erkennen kann
(aber was für eine IDE es ist, is glaub unwichtig?)MfG
Stromberg
-
-
Hä? Nich so lustig!