Re: How do we use an ifstream vector?
* maria:
std::vector <ifstream> in[10];
Uhm, first, an ifstream is not copy-constructible (for what would it
mean to copy a stream?), so you can't place it directly in a vector.
Your compiler should not have accepted that; try to check whether there
is some option to be more standard-conforming (e.g. for g++ -std c++98,
IIRC).
Second, if hypothetically ifstream could serve as vector element type,
the above would declare a raw array of ten empty vectors.
You might instead do
typedef boost::shared_ptr< std::ifstream > IfStreamPtr;
std::vector<IfStreamPtr> in;
Or, from a practical point of view, to avoid having to deal with all
that, but also then coding without a safety net, just use a raw array of
ifstream, default-initialized, and then open() each one.
//
string open_input[10]={
I'll assume that's
std::string const open_input[10] = {
"TEMPLATE_1",
"TEMPLATE_2",
"TEMPLATE_3",
"TEMPLATE_4",
"TEMPLATE_5",
"TEMPLATE_6",
"TEMPLATE_7",
"TEMPLATE_8",
"TEMPLATE_9",
"TEMPLATE_10"
};
How do we open the first 5 files above
by using the vector in?
Are you sure you need to have them all open simultanously?
It would be much, much easier to do one file at a time.
However (disclaimer: off-the-cuff code):
void throwX( char const s[] ) { throw std::runtime_error( s ); }
typedef boost::shared_ptr< std::ifstream > IfStreamPtr;
void open5Files(
std::string const names[], std::vector<IfStreamPtr>& in
)
{
std::vector<IfStreamPtr> result;
for( int i = 0; i < 5; ++i )
{
IfStreamPtr stream( new std::ifstream( names[i] ) );
if( stream->fail() ) { throwX( "blah blah failed" ); }
result.push_back( stream );
}
result.swap( in );
}
void foo()
{
using namespace std;
static string const inFileNames[] = { "a", "b", ... };
vector<IfStreamPtr> inFiles;
open5Files( inFileNames, inFiles );
// Do things
}
This code does some ungood things such as using a magic number (namely
5) and using ifstream pointers rather than abstracting up to istream. I
couldn't recall whether istream has virtual destructor or not. I think
not, and then for abstracting up one would need a custom destruction
function for the boost::shared_ptr.
In short, the so-called /abstraction cost/ seems to be high for this
problem, but might be alleviated by using more suitable library classes.
The raw array and non-exception-based version:
#define ARRAY_SIZE( a ) (sizeof(a)/sizeof(*a))
bool foo()
{
using namespace std;
static char const* const inFileNames[] = { "a", "b", ... };
ifstream inFiles[ARRAY_SIZE(inFileNames)];
assert( ARRAY_SIZE(inFileNames) >= 5 );
for( int i = 0; i < 5; ++i )
{
if( !inFiles[i].open( inFileNames[i] ) )
{
return false;
}
}
// Do things with the files, then:
return true;
}
When I try
for (i=0; i<5; i++) {
if (!in[i](open_input[i].c_str(), ios::in)) {
return 1;
}
It doesn't work.
"Doesn't work" is quite vague...
Cheers, & hth.,
- Alf
Disclaimer: none of code above ever touched by compiler's hands.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?