ifstream array

Hi all, hopefully a nice easy one.

My program has 6 input files, each of which is loaded a line at a time, the data in each is processed and output to a different file until the end of all the input files is reached.

How and what it does isn't really important, however at the minute I have the following:

  ifstream fin0(m_file_paths[1]);
  .
  .
  ifstream fin5(m_file_paths[6]);

  fin0.getline(line, 500, '\n');
  .
  .
  fin5.getline(line, 500, '\n');


What I'd like to do is something like the following (0 is used seperately):

  ifstream fin[6];
  for (i=1; i<6; i++)
  {
    fin[i] = ifstream(m_file_paths[i]);
  }

and then get data using something like:
  fin[1].getline(line, 500, '\n');

The declarations seem to work ok, however it falls over on the getline (which works when they're not in arrays) with the standard "unable to read memory at" error dialogue...

Any ideas where I'm going wrong?

Thanks in advance,

Steve


LVL 2
elstcbAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
AxterConnect With a Mentor Commented:
You can use pointers instead.
Example:

int main(int argc, char* argv[])
{
     char m_file_paths[6][32]  = {"c:\\test1.cpp", "c:\\test2.cpp", "c:\\test3.cpp", "c:\\test4.cpp", "c:\\test5.cpp", "c:\\test6.cpp"};
     char line[6][501];
     ifstream *fin[6];
     for (int i=0; i<6; i++)
     {
          fin[i] = new ifstream(m_file_paths[i]);
          fin[i]->getline(line[i], 500);
     }

     for (int d=0; i<6; i++)delete fin[d];
     system("pause");
     return 0;
}

0
 
abusimbelCommented:
This is a very common error, you are out of the array by 1:

The loop should go from 0 to 5 and not in 1 to 6 because in the momment you'll try to access    fin[6] you'll have a memory exception and in the momment you'll try to acces fin[0] you'll have a non initilized stream.

Remember:

ifstream fin[6];

Has as members:

fin[0]
fin[1]
fin[2]
fin[3]
fin[4]
fin[5]

Bye,
Abusimbel.
0
 
AxterCommented:
Although some compilers like VC++ 6.0, allows you to use the copy constructor for (ios) type, this is not allowed according to the C++ standard.
If your compiler was working properly, it would have given you a compiler error.
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
elstcbAuthor Commented:
That's _NOT_ my problem - As stated originally I'm only using 1 to 5 in my loop because I use 0 differently to the rest. Hence the i<6 rather than <=.
0
 
AxterCommented:
>>That's _NOT_ my problem - As stated originally I'm only >>using 1 to 5 in my loop because I use 0 differently to
>>the rest. Hence the i<6 rather than <=.

That is also a problem.
0
 
AxterCommented:
>>That's _NOT_ my problem - As stated originally I'm only
>>using 1 to 5 in my loop because I use 0 differently to
>>the rest. Hence the i<6 rather than <=.

That is not the reason you're getting an error.
That paticular problem will only stop you from accessing the first ifstream.  It's not making you reach pass the arrray, because you have (<6) in your for loop.

The real problem that is causeing the error you reported is what I have already posted in my first comment.
0
 
abusimbelCommented:
Ok if the array is not the problem, then as Axter said you can use instead:

fin[i] = ifstream(m_file_paths[i]);

fin[i].open(m_file_paths[i]);

And you will avoid the copy constructor.

Another posibility is to use pointers instead objects in the array, but the open should work perfectly.

Bye,
Abusimbel.
0
 
AxterCommented:
A more elagant approach would be to create a small class that can do job where the variable gets declared.

Example:

class Myifstream : public ifstream
{
public:
     Myifstream(const char* FileName) : ifstream(FileName){}
};



int main(int argc, char* argv[])
{
     char line[6][501];
     Myifstream fin[6] = {"c:\\test1.cpp", "c:\\test2.cpp", "c:\\test3.cpp", "c:\\test4.cpp", "c:\\test5.cpp", "c:\\test6.cpp"};
     for (int i=0; i<6; i++)
     {
          fin[i].getline(line[i], 500);
     }

     return 0;
}


Continue....
0
 
AxterCommented:
In my above posted example, you don't need to iterate through fin[] to initialize it and open the file.
It's all done in one line:
Myifstream fin[6] = {"c:\\test1.cpp", "c:\\test2.cpp", "c:\\test3.cpp", "c:\\test4.cpp", "c:\\test5.cpp", "c:\\test6.cpp"};


So in one line, you declare the variable, pass the file name, and open the file.
0
 
AxterCommented:
If you need to use m_file_paths member function in order to open the file, you can still do that with the above class.
Example:
int main(int argc, char* argv[])
{
     char line[6][501];
     char m_file_paths[6][32]  = {"c:\\test1.cpp", "c:\\test2.cpp", "c:\\test3.cpp", "c:\\test4.cpp", "c:\\test5.cpp", "c:\\test6.cpp"};
     Myifstream fin[6] = {m_file_paths[0], m_file_paths[1], m_file_paths[2], m_file_paths[3], m_file_paths[4], m_file_paths[5]};
     for (int i=0; i<6; i++)
     {
          fin[i].getline(line[i], 500);
     }

     system("pause");
     return 0;
}

0
 
AxterCommented:
One last point.
In most cases, it's better to use the member function, then to use a global function.
However, getline function is an exception to the rule.
That's because the getline member function does not have an overloaded function that can take a std::string object directly.
However, the global std::getline function does have this method.
So your code could look like this instead.
int main(int argc, char* argv[])
{
     string line[6];
     char m_file_paths[6][32]  = {"c:\\test1.cpp", "c:\\test2.cpp", "c:\\test3.cpp", "c:\\test4.cpp", "c:\\test5.cpp", "c:\\test6.cpp"};
     Myifstream fin[6] = {m_file_paths[0], m_file_paths[1], m_file_paths[2], m_file_paths[3], m_file_paths[4], m_file_paths[5]};
     for (int i=0; i<6; i++)
     {
          getline(fin[i], line[i]);
     }

     system("pause");
     return 0;
}


By using std::string, you don't have to allocate a big block array variable like the following:
char line[6][501];

More then likely, most of the memory will go to waste, because most lines fall between 2-80 charactors.
But if you use std::string, it will only allocate as much memory as required for the paticular line being read.
0
 
abusimbelCommented:
Axter, Could you divide the answer in more fragments?

;-)

Bye,
Abusimbel.
0
 
AxterCommented:
>>Axter, Could you divide the answer in more fragments?

I was making separate points, and I was affraid I would loose the reader if I put it all in one big chunk.

And my last comment really didn't have to much to do with the original question.  Just FYI....
0
 
elstcbAuthor Commented:
wow that's a lot of replies...!

I'm not at work any more but I'll give it a go tomorrow.

Thanks,

Steve
0
 
AxterCommented:
elstcb,
Did the comment I post fix the problem?
0
 
elstcbAuthor Commented:
Sorry I haven't posted back for a few days, I haven't been able to get access to the file I need to try it out. I should have access again later today or tomorrow so I'll get back to you then.

Steve
0
 
elstcbAuthor Commented:
Thanks it worked a treat. Whilst the other stuff was probably "more elegant" as you put it, it was a bit over my head!

Sorry for the delay in getting back.

Thanks again,

Steve
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.