提问人:arghe 提问时间:8/22/2023 最后编辑:user207421arghe 更新时间:8/22/2023 访问量:54
C++ 在将新联系人添加到联系人列表时,如何确保文件在程序运行之间不会被覆盖?
C++ How do I make sure file is not overwritten between program runs when adding new contacts to a contact list?
问:
我正在尝试为一个简单的通讯录创建一个程序,该程序从用户那里获取有关联系人的信息并将其保存在文件中。当我重新运行程序并下次打开相同的文件时,我显然希望我之前添加的所有联系人仍然存在,并且如果我选择添加新联系人(或者只是退出程序而不添加任何新联系人),则不会被覆盖。 但是我无法正确保存文件。我可以将联系人添加到地图中,但根据我放置 saveToFile() 的位置,文件总是在某个时候覆盖联系人,无论是在添加新联系人之后还是在程序运行之间。
这是我的通讯录和 main 函数调用的类:
#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
struct Contact {
std::string name;
std::string address;
std::string email;
std::string number;
std::string bday;
std::string other;
}
class ContactBook {
private:
std::map<std::string, Contact> contacts;
public:
void ContactBook::loadFromFile(const std::string filename) {
std::ifstream file(filename);
if (!file) {
std::cout << "Unable to open file" << std::endl;
return;
}
std::string line;
while (std::getline(file, line)) {
std::istringstream iss(line);
Contact contact;
if (std::getline(iss, contact.name, '\n') &&
std::getline(iss, contact.address, '\n') &&
std::getline(iss, contact.email, '\n') &&
std::getline(iss, contact.number, '\n') &&
std::getline(iss, contact.bday, '\n') &&
std::getline(iss, contact.other, '\n')) {
contacts[contact.name] = contact;
}
}
file.close();
std::cout << "File " << filename << " loaded" << std::endl;
}
void ContactBook::addContact(const Contact& contact) {
contacts[contact.name] = contact;
}
void ContactBook::saveToFile(const std::string& filename) {
std::ofstream file;
file.open(filename);
for (const auto& pair : contacts) {
const Contact& contact = pair.second;
file << contact.name << '\n' <<
contact.address << '\n' <<
contact.email << '\n' <<
contact.number << '\n' <<
contact.bday << '\n' <<
contact.other << '\n';
} file.close();
}
void ContactBook::printFile(const std::string& filename) {
std::string line;
std::ifstream file;
file.open(filename);
if (file.is_open()) {
while(std::getline(file, line)) {
std::cout << line << '\n';
}
file.close();
}
}
}
int main() {
ContactBook contactBook;
contactBook.load("contacts.txt");
int alt;
bool exit = false;
while (!exit) {
std::cout << "1 - Add contact" << '\n' <<
"2 - Remove contact" << '\n' << //will add later
"3 - Search for contact" << '\n' << //will add later
"4 - Save and exit" << '\n' <<
"5 - Print contact list" << std::endl;
std::cin >> alt;
switch(alt) {
case 1: {Contact contact;
std::cin.ignore();
std::cout << "Name: ";
std::getline(std::cin, contact.name);
std::cout << "Address: ";
std::getline(std::cin, contact.address);
std::cout << "Email: ";
std::getline(std::cin, contact.email);
std::cout << "Phone number: ";
std::getline(std::cin, contact.number);
std::cout << "Birthday: ";
std::getline(std::cin, contact.bday);
std::cout << "Other info: ";
std::getline(std::cin, contact.other);
contactBook.addContact(contact);
}
break;
case 2: /*...*/
break;
case 3: /*..*/
break;
case 4: contactBook.saveToFile("contacts.txt");
exit = true;
break;
case 5: contactBook.printFile("contacts.txt");
break;
default: std::cout << "invalid input" << std::endl;
}
}
return 0;
}
截至目前,如果我添加联系人,保存并重新运行程序并选择打印,则之前添加的联系人将被正确打印。但是,如果我第二次保存并退出,那么下次运行文件将是空的。 如果在同一程序运行期间添加另一个联系人,第一个联系人也将消失 - 如果我保存并退出,文件将仅包含第二个联系人。
对不起,如果我在这里犯了一个超级愚蠢和明显的错误——我是初学者。但我就是想不通,我已经被困了几个小时,以至于我无法再真正专注于我正在做的事情,非常感谢。
答:
您读取文件的方式永远无法工作,因为默认情况下,当它遇到 时会停止读取,因此它永远无法输出包含 a 的文件。但是您期望多个字段位于用 分隔的单行上,这是无稽之谈。std::getline()
'\n'
std::string
'\n'
'\n'
循环的第一次迭代将仅将第一个联系人读入 ,然后后续迭代将无法读入其余值,因为它们在 中不存在。然后,下一次迭代将把第一个联系人读入 ,随后将失败。等等。while
name
istringstream
if
istringstream
while
address
istringstream
if
要执行您正在尝试的操作,请改用其他分隔符,例如 ,例如:'\t'
void ContactBook::loadFromFile(const std::string filename) {
std::ifstream file(filename);
if (!file) {
std::cout << "Unable to open file" << std::endl;
return;
}
std::string line;
while (std::getline(file, line)) {
std::istringstream iss(line);
Contact contact;
if (std::getline(iss, contact.name, '\t') &&
std::getline(iss, contact.address, '\t') &&
std::getline(iss, contact.email, '\t') &&
std::getline(iss, contact.number, '\t') &&
std::getline(iss, contact.bday, '\t') &&
std::getline(iss, contact.other))
{
contacts[contact.name] = contact;
}
}
file.close();
std::cout << "File " << filename << " loaded" << std::endl;
}
void ContactBook::saveToFile(const std::string& filename) {
std::ofstream file(filename);
if (!file) {
std::cout << "Unable to create file" << std::endl;
return;
}
for (const auto& pair : contacts) {
const Contact& contact = pair.second;
file << contact.name << '\t' <<
contact.address << '\t' <<
contact.email << '\t' <<
contact.number << '\t' <<
contact.bday << '\t' <<
contact.other << '\n';
}
file.close();
std::cout << "File " << filename << " saved" << std::endl;
}
否则,如果你想用来分隔你的字段,那么你需要去掉 ,直接读取行,例如:'\n'
std::istringstream
std::ifstream
void ContactBook::loadFromFile(const std::string filename) {
std::ifstream file(filename);
if (!file) {
std::cout << "Unable to open file" << std::endl;
return;
}
Contact contact;
while (std::getline(file, contact.name) &&
std::getline(file, contact.address) &&
std::getline(file, contact.email) &&
std::getline(file, contact.number) &&
std::getline(file, contact.bday) &&
std::getline(file, contact.other))
{
contacts[contact.name] = contact;
}
file.close();
std::cout << "File " << filename << " loaded" << std::endl;
}
void ContactBook::saveToFile(const std::string& filename) {
std::ofstream file(filename);
if (!file) {
std::cout << "Unable to create file" << std::endl;
return;
}
for (const auto& pair : contacts) {
const Contact& contact = pair.second;
file << contact.name << '\n' <<
contact.address << '\n' <<
contact.email << '\n' <<
contact.number << '\n' <<
contact.bday << '\n' <<
contact.other << '\n';
}
file.close();
std::cout << "File " << filename << " saved" << std::endl;
}
评论