I noticed in my C++ code that anytime I close an std::ofstream
object I'm unable to reopen the file I closed with std::ifstream
. std::ifstream
's open
function will always fail.
Is there anything 'extra' I can do to ensure that my std::ofstream object closes properly?
Someone's probably going to ask to see my specific code so for the sake of keeping this post small I've pastied it here. In my code after running through case a or d all std::ifstream
open calls fail. (Prior to posting this question I had several people play with my code who were unable to conclude anything other than that std::ofstream
close failing for unknown reasons)
Thanks in advance to any and all responses received.
Code is
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
typedef struct Entry
{
string Name;
string Address;
string Phone;
};
int main()
{
bool exit = false, found = false;
char input, ch;
string stringinput, stringoutput;
ifstream fin, ibuffer;
ofstream fout, obuffer;
Entry buffer;
while(!exit)
{
cout << "Welcome to the Address Book Application!" << endl << endl;
cout << "\tSelect an option:" << endl << endl;
cout << "\tA -- Add New Entry" << endl;
cout << "\tD -- Delete an Entry" << endl;
cout << "\tS -- Search for an Existing Entry" << endl;
cout << "\tE -- Exit" << endl << endl;
cin >> input;
switch(input)
{
case 'a':
case 'A':
cin.ignore(255,'\n');//Apparently necessary because an extra new line carrys over in the cin stream
system("cls");
//Get Information from User
cout << "Enter Phone Number: ";
getline(cin, buffer.Phone);
cout << endl << "Enter Name: ";
getline(cin, buffer.Name);
cout << endl << "Enter Address: ";
getline(cin, buffer.Address);
/*Copy existing database into a buffer. In other words, back it up*/
fin.open("address.txt");
if(!fin)
{
fin.close();
fout.open("address.txt");
fout << buffer.Phone << endl << buffer.Name << endl << buffer.Address << endl;
}
if(fin)
{
obuffer.open("buffer.txt");
while(fin && fin.get(ch))
obuffer.put(ch);
fin.close();
obuffer.close();
/*Copy buffer to new database file*/
ibuffer.open("buffer.txt");
fout.open("address.txt");//This removes all of the previously existing info from database.txt
while(ibuffer && ibuffer.get(ch))
fout.put(ch);
ibuffer.close();
remove("buffer.txt");//Delete the buffer
fout << endl << buffer.Phone << endl << buffer.Name << endl << buffer.Address << endl;
}
buffer.Phone.erase();
buffer.Name.erase();
buffer.Address.erase();
fout.close();
break;
case 'd':
case 'D':
cin.ignore(255,'\n');//Apparently necessary because an extra new line carrys over in the cin stream
system("cls");
cout << "Enter the phone number of the entry to delete: ";
cin >> stringinput;
fin.open("address.txt");
if(!fin)
{
cout << endl << "No entries exist!";
fin.close();
break;
}
obuffer.open("buffer.txt");
/* Copy everything over into the buffer besides the account we wish to delete */
while(!fin.eof())
{
fin.read(&ch, sizeof(char));
if(ch != '\n' && ch != '\0')
stringoutput += ch;
if(ch == '\n' || ch == '\0')
{
if(stringinput.compare(stringoutput))
{
stringoutput += ch;
obuffer << stringoutput;
stringoutput.erase();
}
if(!stringinput.compare(stringoutput))
{
stringoutput += ch;
getline(fin, stringoutput);
getline(fin, stringoutput);
fin.read(&ch, sizeof(char));//Get rid of the extra '\n'
stringoutput.erase();
}
}
}
//Hack: Copy the last line over since the loop for some reason doesn't
obuffer << stringoutput;
stringoutput.erase();
fin.close();
obuffer.close();
fout.open("address.txt");
ibuffer.open("buffer.txt");
while(ibuffer && ibuffer.get(ch))
fout.put(ch);
ibuffer.close();
fout.close();
remove("buffer.txt");
cout << endl << "Entry " << stringinput << " deleted successfully!" << endl;
stringinput.erase();
stringoutput.erase();
break;
case 's':
case 'S':
cin.ignore(255,'\n');//Apparently necessary because an extra new line carrys over in the cin stream
system("cls");
found = false;
fin.open("address.txt");
if(!fin)
{
cout << "No entries currently exist!" << endl << endl;
fin.close();
break;
}
cout << "Enter the phone number to search for: ";
cin >> stringinput;
while(!fin.eof())
{
fin.read(&ch, sizeof(char));
if(ch != '\n' && ch != '\0')
stringoutput += ch;
if(ch == '\n' || ch == '\0')
{
if(!stringinput.compare(stringoutput))
{
found = true;
break;
}
stringoutput.erase();
}
}
if(found)
{
cout << "Phone Number: " << stringinput << endl;
getline(fin, stringoutput);
cout << "Name: " << stringoutput << endl;
getline(fin, stringoutput);
cout << "Address: " << stringoutput << endl << endl;
}
if(!found)
{
stringoutput.erase();
cout << endl << stringinput << " is not in the address book!" << endl << endl;
}
stringinput.erase();
stringoutput.erase();
fin.close();
break;
case 'e':
case 'E':
exit = true;
break;
default:
system("cls");
cout << input << " is not a valid option." << endl << endl;
break;
}
}
return 0;
}