Als ein Noob-C++ - Projekt erstelle ich ein CLI-Spiel mit einer Spielschleife, die auf Benutzereingaben beruht. Zu Testzwecken möchte ich gerne einen Dateinamen als Kommandozeilenargument an das Programm übergeben, das bis zum Durchlesen "wie Standardeingabe" behandelt wird.Objekt streamen, um die Dateieingabe und dann die Standardeingabe darzustellen?
Folglich brauche ich eine Möglichkeit, ein Objekt zu kapseln, die den Inhalt einer Datei darstellt und dannstd::cin
sobald die Datei durch gelesen wurde - im Grunde den Inhalt einer Datei auf der Standardeingabe vorangestellt wird. Zumindest scheint dies wäre es sehr schön sein, so dass ich etwas mit wie
std::istringstream retrieve_input(std::ifstream &file) {
std::string line;
if (std::getline(file, line))
return std::istringstream{line};
std::getline(std::cin, line);
return std::istringstream{line};
}
ersetzt dies mit irgendeiner Art von benutzerdefinierten Klasse ein guter Ansatz vermeiden kann? Oder kann ich mich irgendwie mit std::cin
anlegen, um meinen Dateiinhalt voranzustellen?
Um zu verdeutlichen: Meine Spielschleife könnte sagen, 20 Iterationen. Wenn ich eine Datei mit fünf Zeilen übergebe, möchte ich diese fünf Zeilen für die ersten fünf Iterationen meiner Spielschleife verwenden und dann für die verbleibenden fünfzehn auf die Standardeingabe zurückgehen. Ich verstehe, wie man das mit einer Reihe von Bedingungen macht, aber ich denke, es muss einen Weg geben, um diese Art von Verhalten in einer Klasse zu haben. Mein Problem ist - was sollte es erben? std::streambuf
? Ist das grundsätzlich eine gute Idee?
Mein (wahrscheinlich schlechter Versuch)
class InputGrabber {
public:
virtual std::istringstream retrieve_line() = 0;
virtual ~InputGrabber() {}
};
class BaseInputGrabber : public InputGrabber {
public:
BaseInputGrabber(std::istream &_in): in{_in} {}
std::istringstream retrieve_line() override {
std::string line;
std::getline(in, line);
return std::istringstream{line};
}
private:
std::istream ∈
};
class VarInputGrabber : public InputGrabber {
public:
VarInputGrabber(std::istream &_in, const std::string &f_name) :
in{_in}, init{std::ifstream(f_name)} {}
std::istringstream retrieve_line() override {
std::string line;
if (std::getline(init, line)) {
return std::istringstream{line};
}
std::getline(in, line);
return std::istringstream{line};
}
private:
std::istream ∈
std::ifstream init;
};
@Ron nicht zustimmen. Einige Standardbibliotheksklassen sollen vererbt werden. 'std :: streambuf' ist genau ein Beispiel. –
@Ron Können Sie die Begriffe "einige" und "alle" unterscheiden? –