Jump to content
  • Advertisement
Sign in to follow this  
chbrules

[C++] Opening multiple files, weird bug

This topic is 4815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well I've created a program to open a list of files that are just different by an ID number, ie. 000015.txt 000017.txt... I'm using the fstream library to read the files, but I'm getting an issue. When it's running through the loop, it will open the first file in the series, but it won't open anymore after that. Say I told it to start at ID 15 and read all the files, it will open 15 read it, close it, and not open the rest of them. Here's the code if you're intersted:
void main()
{
	ofstream out;
	ifstream in;
	std::string date, time, meridian, email, file;
	
	char *i2a = new char[8];
	short unsigned int endnum=0;
	short unsigned int startnum=0;

	//Get values
	cout << "Enter starting ID value: ";
	cin >> startnum;
	cout << endl << "Enter ending ID value: ";
	cin >> endnum;

	system("cls");

	cout << "Ready to open!\n";

	//Open write stream
	out.open("Campaign_Opens.txt");
	out << "id,date,email\n"; //Setup header

	//Process
	for(int i = startnum; i <= endnum; i++)
	{
		//Appropriately create filename to open
		if(i > -1 && i < 10)
		{
			file = ".\\CampaignID00000";
			itoa(i, i2a, 10);
			file += i2a;
			file += "-OpenedEmail.txt";
		}
		else if(i > 9 && i < 100)
		{
			file = ".\\CampaignID0000";
			itoa(i, i2a, 10);
			file += i2a;
			file += "-OpenedEmail.txt";
		}
		else if(i > 99 && i < 1000)
		{
			file = ".\\CampaignID000";
			itoa(i, i2a, 10);
			file += i2a;
			file += "-OpenedEmail.txt";
		}
		else if(i > 999 && i < 10000)
		{
			file = ".\\CampaignID00";
			itoa(i, i2a, 10);
			file += i2a;
			file += "-OpenedEmail.txt";
		}
		else
		{
			file = ".\\CampaignID0";
			itoa(i, i2a, 10);
			file += i2a;
			file += "-OpenedEmail.txt";
		}
		
		//Open file for reading
		in.open( file.c_str() );

		//If the file is valid and opened
		if(in.is_open())
		{
			//Read file data
			while(!in.eof())
			{
				//Get data
				in >> date >> time >> meridian >> email;

				//Write new line out to buffer
				out << i2a << "," << date << " " << time << " " << meridian << "," << email << endl;
			 }

			//Clean up
			in.close();
			file = "";
			date = "";
			time = "";
			meridian = "";
			email = "";

			for(int ii=0; ii < 8; ii++)
			{
				i2a[ii] = NULL;
			}
		}
	}

	//Clean up
	out.close();
	delete [] i2a;
}
I'm not quite sure why it's doing this. While I debug it, it shows the proper filenames to open, it's just not opening them. Any reason why? Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Well atleast:
out << "id,date,email\n"; //Setup header

..should be:
out << id << date << email << "\n"; //Setup header
..if you want to output the values instead of just "email" etc.

I couldnt find the problem why it doesnt open the files, I'm ust too tired ;)




Share this post


Link to post
Share on other sites
I believe you need to .reset() the file object each time in addition to .close()ing it; otherwise, the ifstream already has its eofbit set when you open the second file.

Although I personally would avoid the problem by using an ifstream local to the loop:


for(int i = startnum; i <= endnum; i++) {
// Appropriately create filename to open
// By the way, itoa() is awful - non-standard and ancient. I'll redo
// this part using modern tools:
stringstream filenameBuilder("./CampaignID");
// by the way, use forward slashes in your file names, even on platforms
// where that isn't the filename separator - see here:
// http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.16
filenameBuilder << setfill('0') << setw(6) << i << "-OpenedEmail.txt";
// Now we can open the file:
ifstream in(filenameBuilder.str().c_str());
// Yes, those three lines really replace all of your filename construction
// code, and also create a new ifstream object each time through the loop
// with the appropriate filename. :)

// While possible to read a line. If the file couldn't be opened,
// this will fail right away and do nothing, just as it did before.
// This also fixes the bug whereby .eof() doesn't return true until *after
// a failed read*, which would add a duplicate of the last line to your output
// (assuming I'm thinking clearly).

while(in >> date >> time >> meridian >> email) {
out << i << "," << date << " " << time << " " << meridian
<< "," << email << endl;
} // 'i2a' previously just held a string representation of the number, and
// outputting a number to a stream with operator<< works just fine, so I
// just substituted the actual number there.
}
// No cleanup is needed: this ends the scope so the current ifstream will have
// its destructor called (closing the file automatically), and a new one is
// constructed next time through. None of the strings really need to be
// re-initialized because we'll only ever output them when we were successful
// in reading values into them (this holds for the original code too).
// The i2a buffer didn't need to be cleaned up before, either, but now it
// isn't even present. I'd just like to comment that setting individual
// *characters* to 'NULL', while it may work, is misleading: C++ defines
// NULL as 0, which happens to be the necessary value for null termination,
// but it's really meant to indicate a null *pointer*. For chars, use '\0'
// instead.



This feels much more C++-idiomatic to me too, making use of the powerful RAII paradigm.

Share this post


Link to post
Share on other sites
try making the ifstream in object into a scope variable, and hope the destructor cleans up whatever the hell is wrong with it. change: in.open( file.c_str() ) to ifstream in( file.c_str() )

Just a suggestion, FYI, this may have something to do with the crappy default STL implementation of Visual C++ 6.0 compiler (if thats what you're using)

EDIT: might also want to try a call to in.flush() just before closing the file object.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!