Creating ifstream variables at run time in C++?

  • Context: Comp Sci 
  • Thread starter Thread starter John O' Meara
  • Start date Start date
  • Tags Tags
    Time Variables
Click For Summary

Discussion Overview

The discussion revolves around creating multiple input file streams in C++ at runtime, specifically for copying or appending the contents of various input files to a single output file. The number of input files is determined during program execution, and their names are stored in a linked list. Participants explore the implementation details and potential issues in the provided code.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested
  • Homework-related

Main Points Raised

  • One participant inquires about the proper way to manage multiple input file streams for a variable number of files, suggesting the use of a linked list to store file names.
  • Another participant argues that standard looping constructs should suffice for opening and appending files, without needing specific C++ functionalities.
  • A participant expresses concern that their loop does not increment correctly and only processes the first file, leading to confusion about whether multiple ifstream objects are necessary.
  • Suggestions are made to check the linked list implementation for standard iterators or to create custom iteration methods to facilitate file processing.
  • One participant recommends implementing an iterator pattern for better management of the linked list, emphasizing the importance of maintaining a stable interface for future modifications.
  • Another participant reflects on their learning resources, noting that their current materials do not cover modern C++ features like iterators and templates, and expresses that their programming efforts are primarily for personal interest.

Areas of Agreement / Disagreement

Participants do not reach a consensus on the necessity of multiple ifstream objects or the best approach to iterate through the linked list. There are differing opinions on whether the current implementation is sufficient or if improvements are needed.

Contextual Notes

The discussion highlights limitations in the current implementation, such as the lack of iterators in the linked list and potential issues with file handling. There are also unresolved questions regarding the behavior of the loop and the handling of file streams.

Who May Find This Useful

This discussion may be useful for C++ programmers interested in file handling, linked list implementations, and those looking to understand the challenges of managing dynamic input sources in their applications.

John O' Meara
Messages
325
Reaction score
0
How do you make a number of input file streams, one for each input file so that can copy/append the contents of these files to one output file? The number of input files is only known at run time and varies from run to run of the program. The input file names are first stored in a linked list. Would you use RTTI?

Code:
 int main()
...
charList *ptrFile;
charList filesin; 
ptrFile = &filesin;  // is the linked list object
ifstream ifs;

ofstream ofs;

...

for (int i = 0; i <  ptrFile->getCount(); i++) {
  ifs.open(ptr->getValue(), ios::in);
  ...
  copyFile(ifs, ofs); // copy contents of an input file to the output file
  ifs.close():
  ptrFile = ptrFile->getNextEntry();
}
ofs.close();
return 0;
}
where: getCount(), getValue() and getNextEntry() are member functions of charList, a linked list of input file names. Any suggestions would be appreciated.
 
Physics news on Phys.org
Hey John O' Meara.

I don't think you need any kind of C++ specific functionality for this exercise.

If you are just opening a bunch of files and appending the contents of all files to an output file in the order that they are given, then a loop similar to what you have written should be more than sufficient.

Whatever interface you use for files whether it be the standard file library (fopen, fclose, etc), the Windows Functionality (OpenFile, etc) or some other wrapper library with that functionality, the only thing you will need to remember for each iteration of the loop is a file handle, and at most some kind of temporary buffer to grab data from one file and then throw it into another.

You may however, have to do multiple reads of the input file if the temporary buffer you are using is too small, but you can create a simple function to do a loop to do that (and there is probably a function to do it for you but it's pretty straight forward).

Is there any other kind of purpose you are thinking of including (are you thinking about adding new functionality or extending the code in some way)?
 
Hi chiro, thanks for replying.

As the code I have written stands, it refuses to increment i in the for loop and it only adds the first file entered to the output file; so I was thinking that I needed a separate ifstream object for each input file. and so I thought that the code was wrong. If I add the following piece of code in the proper place to the code I have already given
Code:
 if (!ifs.good()) {
  cout << "A file error occurred.\n"; }
g++ gives the above error after appending the first input file to the output file; while a C++ compiler runs without giving this error but still refuses like I said to increment to loop variable i. I don't entend to add any more functionality to this code. As you say I just want to open a bunch of files and append the contents of all files to one output file. I might find this routine handy for future use in something else, though at the moment I have nothing particular in mind. Thanks again.
 
Ohh I see what you are getting at.

You need to look at if your linked list object has a standard iterator, and if you are using a template class, then look at if that has an iterator (things like linked list in C++ usually do) and if they do, see what it is and its implementation.
 
This is the linked list:
Code:
class charList {
 char value[80];
 charList *nextEntry;
 int count;
public:
  charList() { count = 0; }
  charList(char *v, charList *next) : nextEntry(next), count(0)
  { strcpy(value, v);  }

   char *getValue() { return value; }
   charList *getNextEntry() { return nextEntry; }
   int getCount() { return count; }
   void incrCount() { count++; }
   void addToEndM(char *str);
};

 void charList::addToEndM(char *str)
 {
  if (nextEntry !=NULL)
     nextEntry->addToEndM(str);
   else
      nextEntry = new charList(str, NULL);
 }

 istream& operator>>(istream& is, charList *&cl)
{
   charList *cp = NULL;
   char ch[80];

    cin >> ch;
    while (ch[0] != '!') {
      if (cp != NULL) {
        cp->addToEndM(ch);
       else {
          cp = new charList(ch, cp);
          cp->incrCount();
       }
       cout << "Enter another file to copy: ";
       cin >> ch;
       cp->incrCount();
     }
     cl = cp;
     return is;
  }
As you can see I am not using templates or iterators, just basic C-strings etc.
 
I have a recommendation for you: lots of experienced programmers would look at that and go absolutely ape if they say that kind of code, but I'm going to just make a recommendation without getting too anal.

The recommendation I have is that you implement a set of routines for an iterator: basically a routine that signals to start an iteration, and a routine that returns the next object that does an internal increment (which returns a null pointer if nothing is left).

This is the absolute basics of an iterator. It's good design to have the iterator separate from the class, but it would be very straight-forward to just add these routines to your linked list class and add an extra variable that corresponds to the iterator.

You might wonder what the point of this is and the answer is simple: if you want to iterate through things and have the possibility that the list is changed somehow (either by something within the iteration loop itself or through some sub function in call-stack, or through multi-threaded environments) then you want the iterator to act correctly when all this happens.

At the very least, just add a routine that initializes the iterator and then increments a separate iterator variable to go through the list and return the pointer to the next object with doing the right increment.

What you do this setup is that you setup a while loop (so a while loop as opposed to a do). Something like this:

Code:
LinkedListClass* class = whatever; // Assuming whatever is valid
whatever->InitializeIterator();
ObjectType* objectInstance = NULL;

// Method stores the value of the object in the pointer passed and returns 
// a non-zero return if OK and zero if not.
while(whatever->ReturnNextIteratorObject(&objectInstance))
{
   // Do stuff blah blah with objectInstance
};

I'd recommend that if you are going to be using these kinds of container and template classes that you develop a separate iterator object that allows you to have an interface for iteration: this way you can keep the interface and if you need to change what happens behind the scenes due to changing environments, then you can keep the interfaces without having to change all the code that calls these interfaces.

You get some new programmers that think interfaces are over-kill, but one of the reasons why you want to know what the interface is has to do with when you get into development for a long time and then suddenly realize you need to change a core thing and you nearly lose it if you haven't used the right interfaces (it's easy to change what happens what is underlying the interfaces, but it's a pain to create new ones that are significantly different in what functionality they provide especially if they require major changes).
 
Thank you for your recommendations and patience. I have an old book on: "Programming with class A C++ Introduction to Computer science" that I only got around to this year looking at, I guess it is out of date, though I must say that I have found it interesting, but it doesn't do iterators and only mentions templates in an appendix; so the given problem implied that it could be solved without containers, templates or iterators, I would think? It is only for myself that I am doing this computer programming, It will ever only be a hobby with me. Thank you again.
 

Similar threads

  • · Replies 1 ·
Replies
1
Views
2K
Replies
3
Views
2K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 3 ·
Replies
3
Views
13K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 8 ·
Replies
8
Views
12K