Solved

ifstream array

Posted on 2002-07-25
17
1,097 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
  • 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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

Question has a verified solution.

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

Suggested Solutions

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

809 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