Reuse of File pointer

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Digital Don
    New Member
    • Jan 2007
    • 19

    Reuse of File pointer

    Hi,

    I have been using C++ for the past 6 months and always had a problem of using the same IFSTREAM variable to read multiple files.

    Code:
    do//Repeat while quit not entered
    {
    	ipf.clear();
    	cout<<"\nGive file name (Q for Quit):";
    	cin>>ipf;
    	
    	ipfilename.open(ipf.c_str(),ifstream::in);
    
    	//Not able to reuse the above pointer with new filename (ipf)
    
    	if(ipfilename.fail())
    		. . .
    	else
    	{			
    		while(!ipfilename.eof())
    		{
    			getline(ipfilename,tempread);
    			...
    		}
    		//ipfilename.clear();//Clearing the file pointer –Didn’t work 
    		ipfilename.close();//Closing the file
    	}		
    }while(!(ipf=="Q" || ipf=="quit" || ipf=="Quit" || ipf=="q"));
    Please help with problem...I searched a lot in google but couldnt find the solution...

    I asked a few friends and they gave me an option of using an array of File Pointers instead of reading...which is a waste of memory I feel. I want to know Why am not able to use this way...what am I doing wrong...

    Hoping for solutions...

    will be great if solved...

    Thank You in advance....

    Regards,
    Digital Don
  • macklin01
    New Member
    • Aug 2005
    • 145

    #2
    Good question.

    On the one hand, the istream pointers probably wouldn't take _that_ much memory, but on the other hand, I agree that it's unsatisfactory that you can't take your approach. (Which I feel is more elegant.)

    Are you sure this isn't a compiler bug? Have you tried another compiler?

    Also, I'd recommend trying a smaller code snippet until you can track something down that works. e.g.,

    Code:
    ifstream inputfile; 
    for( int i=0 ; i < 200 ; i++ )
    {
     inputfile.open( "testfile.txt", , ifstream::in );
     inputfile.close();
    }
    See if that compiles and runs cleanly, first. Then, start adding in additional file operations.

    Finally, another option you might consider is putting the ifstream constructory inside your loop. Then, the object will be deallocated from memory on each iteration, getting around any memory waste issues, and probably getting around any silly bugs.

    At any rate, I find it useful to sometimes first test loops with many object creations and/or destructions and watch the memory useage. It can be very helpful for finding bugs, etc. (Although in that case, it's more for debugging my own classes, and not for searching for potential bugs in a compiler.)

    Thanks, and good luck! -- Paul

    Comment

    • Digital Don
      New Member
      • Jan 2007
      • 19

      #3
      Hi Macklin

      Thank You for your response. I am using Visual Studio 2005 and in that I havent got any compiling error.

      It compiles fine and reads input any number of times...

      The loop works fine if an invalid filename is given. when first time a valid filename is given it works and reads it...when a different file name is provided it doesnt open the new file, instead it opens the first file or in case of ifstream constructor putting inside loop, it exits abruptly....

      Why is what I wanna know.
      Thanks again and Hope someone has solution for it...


      Originally posted by macklin01
      Good question.

      On the one hand, the istream pointers probably wouldn't take _that_ much memory, but on the other hand, I agree that it's unsatisfactory that you can't take your approach. (Which I feel is more elegant.)

      Are you sure this isn't a compiler bug? Have you tried another compiler?

      Also, I'd recommend trying a smaller code snippet until you can track something down that works. e.g.,

      Code:
      ifstream inputfile; 
      for( int i=0 ; i < 200 ; i++ )
      {
      inputfile.open( "testfile.txt", , ifstream::in );
      inputfile.close();
      }
      See if that compiles and runs cleanly, first. Then, start adding in additional file operations.

      Finally, another option you might consider is putting the ifstream constructory inside your loop. Then, the object will be deallocated from memory on each iteration, getting around any memory waste issues, and probably getting around any silly bugs.

      At any rate, I find it useful to sometimes first test loops with many object creations and/or destructions and watch the memory useage. It can be very helpful for finding bugs, etc. (Although in that case, it's more for debugging my own classes, and not for searching for potential bugs in a compiler.)

      Thanks, and good luck! -- Paul

      Comment

      • horace1
        Recognized Expert Top Contributor
        • Nov 2006
        • 1510

        #4
        before you can use ipfilename again you need to clear the error condition from the eof of the previous file, e.g.
        Code:
            do//Repeat while quit not entered
        {
        	ipf.clear();
        	cout<<"\nGive file name (Q for Quit):";
        	cin>>ipf;
        	cout << ipf << endl;
        	ipfilename.clear();   //  clear any error condition!
        	ipfilename.open(ipf.c_str(),ifstream::in);
        
        	//Not able to reuse the above pointer with new filename (ipf)
        
        	if(ipfilename.fail())
               {
                cout << "\nUnable to open file " << ipf << " " << strerror(errno);
                cin.get();cin.get();
                return 1;                                                 // open failed
                }
         	else
        	{			
        		while(!ipfilename.eof())
        		{
        			getline(ipfilename,tempread);
        			cout << tempread << endl;
        		}
        		//ipfilename.clear();//Clearing the file pointer –Didn’t work ?
        		ipfilename.close();//Closing the file
        	}		
        }while(!(ipf=="Q" || ipf=="quit" || ipf=="Quit" || ipf=="q"));

        Comment

        • Digital Don
          New Member
          • Jan 2007
          • 19

          #5
          Thank You Man...I used Clear at the end before close and it worked fine...


          Originally posted by horace1
          before you can use ipfilename again you need to clear the error condition from the eof of the previous file, e.g.
          Code:
          do//Repeat while quit not entered
          {
          	ipf.clear();
          	cout<<"\nGive file name (Q for Quit):";
          	cin>>ipf;
          	cout << ipf << endl;
          	ipfilename.clear(); // clear any error condition!
          	ipfilename.open(ipf.c_str(),ifstream::in);
           
          	//Not able to reuse the above pointer with new filename (ipf)
           
          	if(ipfilename.fail())
          {
          cout << "\nUnable to open file " << ipf << " " << strerror(errno);
          cin.get();cin.get();
          return 1; // open failed
          }
          	else
          	{			
          		while(!ipfilename.eof())
          		{
          			getline(ipfilename,tempread);
          			cout << tempread << endl;
          		}
          		//ipfilename.clear();//Clearing the file pointer –Didn’t work ?
          		ipfilename.close();//Closing the file
          	}		
          }while(!(ipf=="Q" || ipf=="quit" || ipf=="Quit" || ipf=="q"));

          Comment

          Working...