Thread: Changing ifstream's source file in a while loop

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    127

    Changing ifstream's source file in a while loop

    Hi,

    Say you have a program that opens multiple files and reads text from each of them. Is there any way to do this using a while loop, so that you use an integer for the number of each file, and then change what ifstream reads in by using this integer? Basically the following example should show what I'm trying to do.

    1.txt is just 3 lines:
    blah1
    blah2
    blah3

    2.txt is also 3 lines:
    whatever1
    whatever2
    whatever3

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    using namespace std;
    
    int main()
    {
        char stuff_extracted[99];
        char filename[20] = "1.txt";
        ifstream file_in(filename);
        int filenumber = 1;
        char string1[20];
        while (1)
        {
            if (filenumber == 2)
            {
                strcpy_s(filename, "2.txt");
                ifstream file_in(filename);
            }
            file_in.getline(stuff_extracted, 99);
            cout << stuff_extracted << endl << endl;
            if ((filenumber == 1) && (file_in.eof()))
                filenumber = 2;
            else if ((filenumber == 2) && (file_in.eof()))
                return 0;
        }
    }
    This may not seem necessary when you've only got 2 files but if you've got 10 files you want to read in, something like this would be more useful.

    So can anyone help me out with this or have I not explained the problem well enough?

    Thanks.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You can use .open and .close inside the loop to open and close each file (and maybe an array of strings for the filenames).

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> ifstream file_in(filename);

    Take that line out of the beginning of main. Also take it out of the if (filenumber == 2) block. Move it to just outside (below) that if block.

    Your while loop runs once per file, right? So the idea is to create the ifstream object inside that loop. Then you will have a nice clean ifstream object each time you need it (each time the loop is run). You can't do it inside the if block or it will go out of scope at the closing brace of that block.

    This also follows the good practice of declaring your variables only when you need them. Putting a bunch of variables at the top of the function is discouraged in C++. Instead, declare them when you are ready to use them.

    Note that you could declare the ifstream before the loop and use open and close as tabstop suggested, but that is less clear and would likely require more work (like a call to clear() to clear previous failbit or eofbit flags).

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    127
    Quote Originally Posted by tabstop View Post
    (and maybe an array of strings for the filenames).
    Would something like this be suitable? This may sound a silly question but it seems like there are a million different ways to do everything in C++.

    Code:
    string filenames[3] = {"1.txt", "2.txt", "3.txt"};
    Quote Originally Posted by Daved View Post
    Your while loop runs once per file, right?
    Thanks for replying, I appreciate it, but basically I want to check for some stuff in each file later in the while loop, meaning that the while loop will run more than once per file.

    Code:
    Note that you could declare the ifstream before the loop and use open and close as tabstop suggested, but that is less clear and would likely require more work (like a call to clear() to clear previous failbit or eofbit flags).
    Yeah I had some fun figuring this out earlier today (just kidding, I seriously appreciate your help anyway tabstop). Thanks for pointing that out all the same.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Would something like this be suitable?
    It depends on what the actual filenames are. If they are really that basic, I'd build the name on the fly with a stringstream. Use an integer variable as a counter and then combine the counter with the rest of the filename to create the full name each time through the loop:
    Code:
    std::ostringstream ostr;
    ostr << counter << ".txt";
    // str() gets a string from the stringstream and c_str() allows the fstream to read it
    std::ifstream file(ostr.str().c_str());
    >> meaning that the while loop will run more than once per file
    Ok, so if you aren't calling open() every time through the loop, then using open might be better than declaring the ifstream inside. Still, better practice in general is to declare the variable as late as you can.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  4. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM