我有一个奇怪的问题。我正在编写一个函数来从其他地方创建的名称列表中删除一行,经过一些研究,它似乎应该相当简单。我将当前的名称列表写入列表,显示列表,让用户输入要删除的名称,从列表中删除用户输入的名称,然后将更新的列表显示给用户。
到目前为止,一切都运行良好,但是当我将列表写回文件时,姓氏会随机删除一些字符,从几个字符到整行。现在,这就是它变得奇怪的地方。如果我打开文件并在不退出程序的情况下查看它,文件的最后一行就会搞砸,并且只要我稍后在程序中显示它就会继续。但是,如果我退出程序然后打开文件,最后一行将回到原来的编写方式!在写入列表后,程序不会再写入该文件,因此我无法想象为什么会发生这种情况。
我几乎已经决定,由于文件最终来自程序正确,我可以忽略该问题,但我希望用户能够在删除后查看名称列表,原因有多种,这是不可能的而最后一个列表项打印不正确。
我仍然是C ++的初学者,所以我有点希望这只是我没有完全理解列表或其他东西的问题。无论如何,愚蠢的解释将是王牌。
我在下面添加了这个功能,非常感谢任何帮助。
char act, charname[50];
string namestr;
list <string> c1;
list <string>::iterator c1_Iter;
//write the names from the file into a list
ifstream names("List of Names.txt");
while (std::getline(names, namestr))
{
c1.push_back(namestr);
}
//print the current names
cout << "Registered names:";
for (c1_Iter = c1.begin(); c1_Iter != c1.end(); c1_Iter++)
cout << "\n" << setw(5) << " " << *c1_Iter;
//choose which names to delete and confirm
cout << "\n\nEnter the name you would like to delete: ";
cin.getline(charname, 50);
cin.getline(charname, 50);
cout << "\nAre you sure? Enter 'y' to permanently delete " << charname << ", and any other key to return to the start screen.";
cin >> act;
if (act == 'y' || act == 'Y')
{
//delete a file associated with each name
string strname(charname);
strname.append(".txt");
if (remove(strname.c_str()) < 0)
perror("Error deleting file");
else
{
//delete name from the file only if that person's individual file is successfully deleted
c1.remove(charname);
cout << "\n" << charname << " successfully deleted!\n";
//print the updated list of names
cout << "\nUpdated list of registered names:\n";
for (c1_Iter = c1.begin(); c1_Iter != c1.end(); c1_Iter++)
cout << *c1_Iter << endl;
//write updated list of names over "List of Names" to update the file
ofstream newNames("List of Names.txt");
for (c1_Iter = c1.begin(); c1_Iter != c1.end(); c1_Iter++)
newNames << *c1_Iter << endl;
newNames.close();
}
}
答案 0 :(得分:3)
正如Mohit Jain在评论中提到的那样,您需要在names.close()
上致电ifstream
,然后再打开文件作为单独的ofstream
进行书写。此外,您可以使用std::string charname
而不是char charname[50]
。
您还可以使用fstream
进行适当的搜索。如果我没有弄错,那么处理同一文件的活动ifstream
和ofstream
对象会导致未定义的行为。
这是一个更加C ++友好的解决方案:
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <iomanip>
int main()
{
char act;
std::string charname;
std::string namestr;
std::list<std::string> c1;
std::list<std::string>::iterator c1_Iter;
//write the names from the file into a list
std::ifstream names("names.txt");
while (std::getline(names, namestr))
{
c1.push_back(namestr);
}
//print the current names
std::cout << "Registered names:";
for (c1_Iter = c1.begin(); c1_Iter != c1.end(); c1_Iter++)
std::cout << "\n" << std::setw(5) << " " << *c1_Iter;
//choose which names to delete and confirm
std::cout << "\n\nEnter the name you would like to delete: ";
std::cin >> charname;
std::cout << "\nAre you sure? Enter 'y' to permanently delete " << charname << ", and any other key to return to the start screen.";
std::cin >> act;
if (act == 'y' || act == 'Y')
{
//delete a file associated with each name
std::string strname(charname);
strname.append(".txt");
if (remove(strname.c_str()) < 0)
{
std::cerr << "Error deleting file " << strname << std::endl;
return 1;
}
else
{
//delete name from the file only if that person's individual file is successfully deleted
c1.remove(charname);
std::cout << "\n" << charname << " successfully deleted!\n";
//print the updated list of names
std::cout << "\nUpdated list of registered names:\n";
for (c1_Iter = c1.begin(); c1_Iter != c1.end(); c1_Iter++)
std::cout << *c1_Iter << std::endl;
//write updated list of names over "List of Names" to update the file
names.close(); //Close the ifstream before opening the file for editing
std::ofstream newNames("names.txt");
for (c1_Iter = c1.begin(); c1_Iter != c1.end(); c1_Iter++)
newNames << *c1_Iter << std::endl;
newNames.close();
}
}
return 0;
}