Pregunta
Cuando intento compilar el código
istream in;
if (argc==1)
in=cin;
else
{
ifstream ifn(argv[1]);
in=ifn;
}
gcc falla, quejándose de que operator=
es privado.¿Hay alguna manera de establecer un istream
a diferentes valores según una condición?
Solución
Puede reemplazar streambuf de cin con otra, y, en algunos programas esto es más simple que la estrategia general de pasar alrededor de iStreams sin hacer referencia a cin directamente.
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;
}
A pesar de que es extremadamente raro de usar cin después del control deja principal, lo anterior try-catch evita un comportamiento indefinido si eso es algo que su programa podría hacer.
Otros consejos
Se puede usar un puntero para in
, ej .:
istream *in;
ifstream ifn;
if (argc==1) {
in=&cin;
} else {
ifn.open(argv[1]);
in=&ifn;
}
Por lo tanto, se quejaba que no "ningún constructor apropiada disponible"? De todas formas, se puede modificar de la siguiente manera.
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);
}
}
No se puede afectar los flujos de este tipo. Lo que se quiere lograr puede obtenerse utilizando un puntero a un istream sin embargo.
#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'
// ...
}