Вопрос
Когда я пытаюсь собрать код
istream in;
if (argc==1)
in=cin;
else
{
ifstream ifn(argv[1]);
in=ifn;
}
GCC терпит неудачу, жалуясь, что operator=
является частным. Есть ли способ установить istream
к разным значениям на основе условия?
Решение
Вы можете заменить CIN's Streambuf другим, и в некоторых программах это проще, чем общая стратегия передачи ISTREAMS, не обращаясь к CIN напрямую.
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;
}
Несмотря на то, что это крайне редко использовать CIN после того, как контролирует листья Main Main, вышеупомянутая попытка избежать неопределенного поведения, если это может сделать ваша программа.
Другие советы
Вы можете использовать указатель для in
, например:
istream *in;
ifstream ifn;
if (argc==1) {
in=&cin;
} else {
ifn.open(argv[1]);
in=&ifn;
}
Итак, не жалуется ли «нет подходящего конструктора»? В любом случае, вы можете изменить его, как показано ниже.
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);
}
}
Вы не можете повлиять на такие потоки. То, что вы хотите достичь, может быть получено с использованием указателя на Istream.
#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'
// ...
}