Solved

ifstream array

Posted on 2002-07-25
17
1,098 Views
Last Modified: 2012-06-27
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


0
Comment
Question by:elstcb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 4
  • 3
17 Comments
 
LVL 3

Expert Comment

by:abusimbel
ID: 7177360
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
 
LVL 30

Expert Comment

by:Axter
ID: 7177535
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
 
LVL 2

Author Comment

by:elstcb
ID: 7177548
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 30

Expert Comment

by:Axter
ID: 7177560
>>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
 
LVL 30

Expert Comment

by:Axter
ID: 7177575
>>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
 
LVL 3

Expert Comment

by:abusimbel
ID: 7177603
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
 
LVL 30

Accepted Solution

by:
Axter earned 50 total points
ID: 7177630
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
 
LVL 30

Expert Comment

by:Axter
ID: 7177648
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
 
LVL 30

Expert Comment

by:Axter
ID: 7177659
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
 
LVL 30

Expert Comment

by:Axter
ID: 7177671
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
 
LVL 30

Expert Comment

by:Axter
ID: 7177687
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
 
LVL 3

Expert Comment

by:abusimbel
ID: 7177707
Axter, Could you divide the answer in more fragments?

;-)

Bye,
Abusimbel.
0
 
LVL 30

Expert Comment

by:Axter
ID: 7177747
>>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
 
LVL 2

Author Comment

by:elstcb
ID: 7178095
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
 
LVL 30

Expert Comment

by:Axter
ID: 7181664
elstcb,
Did the comment I post fix the problem?
0
 
LVL 2

Author Comment

by:elstcb
ID: 7185488
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
 
LVL 2

Author Comment

by:elstcb
ID: 7186260
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

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question