J'ai remarqué dans mon code C++ qu'à chaque fois que je ferme un objet std::ofstream
, je suis incapable de rouvrir le fichier que j'ai fermé avec std::ifstream
. La fonction open
échouera toujours.Une raison pour laquelle un objet std :: ofstream ne se fermera pas correctement?
Y a-t-il quelque chose de 'extra' que je puisse faire pour m'assurer que mon objet std :: ofstream se ferme correctement?
Quelqu'un va probablement demander à voir mon code spécifique donc pour le plaisir de garder ce post petit, je l'ai fait coller here. Dans mon code après avoir parcouru le cas a ou d tous les appels ouverts std::ifstream
échouent. (Avant de poster cette question, j'avais plusieurs personnes qui jouaient avec mon code et qui étaient incapables de conclure quelque chose d'autre que std::ofstream
fermer pour des raisons inconnues)
Merci d'avance pour toutes les réponses reçues.
codeest
#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;
}
Il serait utile de savoir quels objets de flux sont la cause de votre chagrin et à quelle ligne dans le code vous avez frappé l'erreur. –
Dans mon code spécifiquement après je fout.close() je suis incapable de fin.open() –
Nous aimons toujours garder le code dans la question de sorte que le poste SO est plus autonome et utile lorsque cette pâte meurt inévitablement. S'il vous plaît réduire à un test plus petit et inclure dans la question. –