Weltraumvernichtungssimulator
-
Woher kommt "put" hab ich noch nie gehört davon....
? Ist "put" sowas wie "<<"?http://www.cplusplus.com/reference/iostream/ostream/put.html ... nein. std::ostream::put(char c) ist eine Funktion, std::ostream::operator<< ist ein Stream-Operator.
warum führt das denn dann eigentlich nicht zu einer, ist doch so n ähnliches System
Nope. Du überlädst da ja den operator<< für game::part und nicht für std::string. data.question ist aber ein std::string!
Als was wird den eigentlich " " angesehen, als C-String, also char?
er sollte es als const char* interpretieren: { ' ', '\0' } ...
Und was wäre wenn das noch "BLABLA" stände
{ 'B', 'L', 'A', 'B', 'L', 'A', '\0' } => const char* ...
-
Stromberg schrieb:
@camper
Warum ist das ganz schön burtal? Stimmts etwa doch nicht? Des hatt mich jetzt bissel verwirrt.Ist keine Frage von stimmen. Es verändert die Semantik einer bereits wohldefinierten Operation in nichttrivialer Weise. Das es überhaupt geht, ist nur dem Zufall geschuldet (hier: die normale Überladung für diesen Fall ist eine Templatefunktion).
-
Also bist du eher der Meinung das des schlechter Stil ist oder wie? Aber eigentlich macht des doch nix, weil es hätte doch sowieso nen Compilierfehler gegeben wenn man einfach nach dem "<<" ein game::part objekt hingesetzt hätte oder? Ich versteh jetzt net so ganz.
MfG
Stromberg
-
Noch kurz was, wie kann ich mir den das jetzt genau vorstellen, wenn da jetzt steht:
..... game::part objekt; cout << objekt; ..... std::ostream& operator<< (std::ostream& out, const game::part& data) { out << data.question << "\n"; for (std::size_t i = 0; i < 3; ++i) out << data.answer[i] << "\n"; return out; }was passiert dann jetzt genau bei "cout << objekt" und bei "return out", steht da dann zum schluss irgendwie dann des cout und das out?
cout << out;Kann ich mir das so im Kopf vorstellen?
MfG
Stromberg
-
Du kannst dir
cout << objektals
operator<<(cout, objekt)vorstellen, dann sollte es dir eigentlich klar werden.
Das "return out;" erlaubt dir, Aufrufe des operator<< zu verketten:
cout << objekt1 << objekt2; // ist das gleiche wie: operator<<(operator<<(cout, objekt1), objekt)
-
Noch eine Frage, (D)Evil hat am anfang gesagt ich soll die Initialisierungsliste nutzen, aber qrum hat er nur "question" in die Initialisierungsliste genommen?
part(const std::string& question, const std::string answer_a, const std::string& answer_b, const std::string& answer_c, const std::string& effect_one, const std::string& effect_two, const std::string& effect_three) : question(question) { answer[0] = answer_a; answer[1] = answer_b; answer[2] = answer_c; effect[0] = effect_one; effect[1] = effect_two; effect[2] = effect_three; }[siehe Seite 2 oben)
MfG
Stromberg
-
Stromberg schrieb:
Noch eine Frage, (D)Evil hat am anfang gesagt ich soll die Initialisierungsliste nutzen, aber qrum hat er nur "question" in die Initialisierungsliste genommen?
Weil du Arrays in Konstruktor-Initialisierungslisten nur default konstruiert werden können. Das ist mal ein Fall, wo du die Initialisierungsliste verzichten musst.
-
Kann mir jemand folgende Zeile aus (D)Evils Code erklären:
while (!(std::cin >> answer) || answer < 1 || answer > 3) { std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); }Den Anfang verstehe ich noch, das sind die Abfragen ob auch nichts anderes als eine Zahl zwischen 1 u. 3 gedrückt worden ist. Und das while wiederholt den Vorgang dann irgendwie solange bis eine richtige Taste gedrückt wurde. Aber was ist das alles mit dem cin? clear()? ignore()? numeric_limits? <streamsize>::max()?
MfG
Stromberg
-
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n');Die Zeile sieht sehr verwirrend aus, ist aber eigentlich einfach

Und zwar verwirft der Stream "cin" alle Daten, die im Moment anliegen. Dabei verwirft er Zeichen für Zeichen so lange, bis er auf ein '\n' (also neue Zeile) stößt, oder die angegebene Anzahl an zu verwerfenden Zeichen (in dem Fallstd::numeric_limits<std::streamsize>::max()) erreicht ist.std::numeric_limits<std::streamsize>::max()deshalb, weil das die größte "Zahl" ist, die man hier als Argument angeben kann
-
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