Lire à partir cin ou un fichier
Question
Lorsque je tente de compiler le code
istream in;
if (argc==1)
in=cin;
else
{
ifstream ifn(argv[1]);
in=ifn;
}
gcc échoue, se plaignant que operator=
est privé. Est-il possible de définir une istream
à des valeurs différentes en fonction d'une condition?
La solution
Vous pouvez remplacer la streambuf de cin avec un autre, et dans certains programmes c'est plus simple que la stratégie générale de passage iStreams autour sans se référer à cin directement.
int main(int argc, char* argv[]) {
ifstream input;
streambuf* orig_cin = 0;
if (argc >= 2) {
input.open(argv[1]);
if (!input) return 1;
orig_cin = cin.rdbuf(input.rdbuf());
cin.tie(0); // tied to cout by default
}
try {
// normal program using cin
}
catch (...) {
if (orig_cin) cin.rdbuf(orig_cin);
throw;
}
return 0;
}
Même si il est extrêmement rare d'utiliser cin après le départ de contrôle principal, le try-catch ci-dessus permet d'éviter un comportement non défini, si c'est quelque chose de votre programme pourrait faire.
Autres conseils
Vous pouvez utiliser un pointeur pour in
, .: par exemple
istream *in;
ifstream ifn;
if (argc==1) {
in=&cin;
} else {
ifn.open(argv[1]);
in=&ifn;
}
Alors, est-il pas plaint « aucun constructeur approprié disponible »? Quoi qu'il en soit, vous pouvez le modifier comme ci-dessous.
void Read(istream& is)
{
string line;
while (getline(is, line))
cout << line;
}
int main(int argc, char* argv[])
{
if (argc == 1)
Read(cin);
else
{
ifstream in("sample.txt");
Read(in);
}
}
Vous ne pouvez pas affecter les flux comme celui-ci. Qu'est-ce que vous voulez atteindre peut être obtenu à l'aide d'un pointeur sur un istream bien.
#include <fstream>
#include <istream>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
istream *in;
// Must be declared here for scope reasons
ifstream ifn;
// No argument, use cin
if (argc == 1) in = &cin;
// Argument given, open the file and use it
else {
ifn.open(argv[1]);
in = &ifn;
}
return 0;
// You can now use 'in'
// ...
}