Thread: opening files sequentially

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    83

    opening files sequentially

    hi,

    i have a problem with my following code. i'm trying to open 15 files sequentially named file01.txt to file15.txt. the very first file is opening and the program displays the contents perfectly. however i'm having problems opening file02.txt to file15.txt even though these files exist and the contents are the same as file01.txt. any help with debugging is greatly appreciated.

    thanks.

    Code:
    void open_files()
    {
    string newfilename = "", extension = ".txt", filename = "", numstr = "", line = "";
    char buffer[258] = "", numchr[3] = "";
    ifstream file;
    int num_of_files = 15;
    
    	for(int file_number = 1; file_number < num_of_files + 1; file_number++)
    	{
    		if(file_number < 10)
    			newfilename = "file0";
    		if(file_number > 9)
    			newfilename = "file";
    
    		itoa(file_number, numchr, 10);
    		numstr = numchr;
    		newfilename = newfilename + numstr + extension;
    
    		file.open(newfilename.c_str());
    
    		if(file.fail())
    			cout << "file open failed!" << endl;
    
    		while(!file.eof())
    		{
    			file.getline(buffer, 258-1);
    			line = buffer;
    			cout << line << endl;
    		}
    	}
    }

  2. #2
    VA National Guard The Brain's Avatar
    Join Date
    May 2004
    Location
    Manassas, VA USA
    Posts
    903
    I had the same problem when I tried to re-use my fstream objects.. all you have to do is call the .clear( ) member each time before you want to open an additional file.
    Last edited by The Brain; 12-20-2006 at 09:35 PM.
    • "Problem Solving C++, The Object of Programming" -Walter Savitch
    • "Data Structures and Other Objects using C++" -Walter Savitch
    • "Assembly Language for Intel-Based Computers" -Kip Irvine
    • "Programming Windows, 5th edition" -Charles Petzold
    • "Visual C++ MFC Programming by Example" -John E. Swanke
    • "Network Programming Windows" -Jones/Ohlund
    • "Sams Teach Yourself Game Programming in 24 Hours" -Michael Morrison
    • "Mathmatics for 3D Game Programming & Computer Graphics" -Eric Lengyel

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    83
    hi,

    thanks for your response.

    i tried file.clear() at the beginning and the end of the for-loop and i'm still receiving the same output and issues as before. i forgot to clear my fstream object and now i am. i have a feeling that the problem is in converting the number to character/string. but i'm creating 1 the same way 2 to 15 are created and 1 is fine.

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    what about closing file after you finish with it?

    and also you should read Why it's bad to use feof() to control a loop
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    83
    ok. now i have:

    Code:
    	file.close();
    	file.open(newfilename.c_str());
    and still the same.

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    	const int num_of_files = 2;
    	for(int file_number = 1; file_number < num_of_files + 1; file_number++)
    	{
    		string newfilename ("c:\\test");
    		newfilename += file_number/10 + '0';
    		newfilename += file_number%10 + '0';
    		newfilename += ".txt";
    		
    		ifstream file;
    		file.open(newfilename.c_str());
    		
    		if(file.fail())
    			cout << "file open failed!" << endl;
    		else
    			while(!file.eof())
    			{
    				char buffer[258];
    				file.getline(buffer, sizeof (buffer));
    				string line(buffer);
    				cout << line << endl;
    			}
    	}
    That's what I've tried and it IS reading 2 files...
    Maybe you should just debug your app and see where is the problem?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> and still the same.
    Where is the call to clear()? That should be there as well, probably after the close and before the open.

    A better solution would be to just declare your ifstream variable inside the for loop. It is better practice to restrict your variables to the smallest scope you need. In this case you will get the added benefit of automatic closing of the stream and clearing of any error bits.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Posts
    83
    hi everyone,

    the following works fine after the .clear() and .close() suggestion. the .clear() is completely new to me. i also debugged the heck out of it and found out that when my num_of_files is greater than the files found, it goes in an infinite loop but that can be fixed by sending num_of_files to the open_files() function.



    Code:
    void open_files()
    {
    string newfilename = "", extension = ".txt", filename = "", numstr = "", line = "";
    char buffer[258] = "", numchr[3] = "";
    ifstream file;
    int num_of_files = 5;
    
    	for(int file_number = 1; file_number < num_of_files + 1; file_number++)
    	{
    		if(file_number < 10)
    			newfilename = "file0";
    		if(file_number > 9)
    			newfilename = "file";
    
    		itoa(file_number, numchr, 10);
    		numstr = numchr;
    		newfilename = newfilename + numstr + extension;
    
    		file.close();					// new addition
    		file.clear();					// new addition
    		file.open(newfilename.c_str());
    
    		if(file.fail())
    		{
    			cout << "file open failed!" << endl;
    			break;
    		}
    
    		while(!file.eof())
    		{
    			file.getline(buffer, 258-1);
    			line = buffer;
    			cout << line << endl;
    		}
    	}
    }

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > while(!file.eof())
    Why are you still doing this?

    > file.getline(buffer, 258-1);
    Since file.getline(line) also works, why mess with a char array at all?

    In fact,
    while ( file.getline(line) ) cout << line << endl;
    is all you need.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Here is how I'd do it. Many minor changes particular to how I typically do things. Changing all of your formating code to a single line using a stringstream object and opening the file using that stringstream object's str member function to turn it into a string and then of course the string's c_str member function directly after that to get a character pointer that the file stream's constructor expects. The declaration of the file stream object in the scope of the loop as opposed to being outside the loop means that it will automatically close and be cleared of any error flags within each run through the loop so you don't need to use the clear and close functions.

    One important point is there is a problem with how you are doing the loop through the file to read data. You shouldn't use eof to control looping, it can be problematic, you may end up seeing the last line of data from the file twice. Better is to use the return value from the getline call itself to determine whether the read succeeds or not. Also, there is a string version of getline that I've used below as opposed to the char array version. This cleans up things a bit, you don't need the character array and the extra line of code that converts the array to a string before output... actually you don't need to convert at all, you could have just output the array directly.
    Code:
    #include <sstream>
    #include <iomanip>
    
    ...
    
    void open_files()
    {
        string extension = ".txt", line;
        int num_of_files = 5;
    
        for(int file_number = 1; file_number <= num_of_files; file_number++)
        {
            // Declare the stringstream and format the file name
            stringstream sstr;
            sstr << "file" << setw(2) << setfill('0') << file_number << extension;
    
            // Declare and open the file
            ifstream file(sstr.str().c_str());
    
            if(file.fail())
            {
                cout << "file open failed!" << endl;
                continue;
            }
    
            // This is a better way to loop through a file
            while( getline(file,line) )
            {
                cout << line << endl;
            }
        }
    }
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Opening ASCII files in C?
    By Mavix in forum C Programming
    Replies: 6
    Last Post: 04-25-2007, 02:23 PM
  2. Need help opening a series of files
    By ramparts in forum C Programming
    Replies: 9
    Last Post: 11-14-2006, 05:49 PM
  3. Opening files with UNICODE file names
    By decohk in forum Linux Programming
    Replies: 2
    Last Post: 11-09-2006, 05:25 AM
  4. opening files
    By angelic79 in forum C Programming
    Replies: 3
    Last Post: 10-19-2004, 06:52 AM
  5. Opening files - Giving options?
    By wwwGazUKcom in forum C++ Programming
    Replies: 3
    Last Post: 09-18-2001, 07:06 AM