我正在尝试从文本文件中删除包含用户名和密码的行。 所以我试着跟着,
1)阅读文本文件。
2)将userName和密码存储在文本文件中。
3)提示用户要删除哪个用户。
4)如果输入与向量中的用户名匹配,则整个行将在向量中删除。
5)复制回文本文件(尚未完成)
我设法通过运气得到它 的文本文件(userInfo.txt)
amber abc
janet def
chris DEF
gerald AZC
我的代码输出
Before Deletion
amber abc
janet def
chris DEF
gerald AZC
Enter User Name to delete: amber
After Deletion
janet def
chris DEF
gerald AZC
但我真正理解的是,我的代码在与我的输入匹配之后实际上删除了整行,特别是从
开始 string name;
cout << "Enter User Name to delete: ";
cin >> name;
cout << " " << endl;
cout << "After Deletion" << endl;
for (int i =0; i<userDetails.size(); i++) {
if(userDetails[i].getUserName() == name){
userDetails.erase(userDetails.begin() + i);
}
cout << userDetails[i].getUserName() << " " << userDetails[i].getPassword() << "\n";
}
我希望有人可以向我解释。
我的代码
user.h
#ifndef user_user_h
#define user_user_h
#include <iostream>
class user {
public:
user() {
userName = " ";
password = " ";
}
user(std::string userName,std::string password);
std::string getUserName();
std::string getPassword();
void setUserName(std::string userName);
void setPassword(std::string password);
private:
std::string userName,password;
};
#endif
的main.cpp
#include "user.h"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
user::user(string userName,string password) {
setUserName(userName);
setPassword(password);
};
string user::getUserName() {
return userName;
}
string user::getPassword() {
return password;
}
void user::setUserName(std::string userName) {
this->userName = userName;
}
void user::setPassword(std::string password) {
this->password = password;
}
int main(){
vector<user> userDetails;
string line;
string userName;
string password;
ifstream readFile("userInfo.txt");
while(getline(readFile,line)) {
stringstream iss(line);
iss >> userName >> password;
user userInfoDetails(userName,password);
userDetails.push_back(userInfoDetails);
}
readFile.close();
cout << "Before Deletion" << endl;
for (int i =0; i<userDetails.size(); i++) {
cout << userDetails[i].getUserName() << " " << userDetails[i].getPassword() << "\n";
}
cout << " " << endl;
string name;
cout << "Enter User Name to delete: ";
cin >> name;
cout << " " << endl;
cout << "After Deletion" << endl;
for (int i =0; i<userDetails.size(); i++) {
if(userDetails[i].getUserName() == name){
userDetails.erase(userDetails.begin() + i);
}
cout << userDetails[i].getUserName() << " " << userDetails[i].getPassword() << "\n";
}
}
答案 0 :(得分:1)
我不确定我理解你不明白但我会尽力帮助......
您删除了正确位置的行
您为erase
方法提供了一个指向要删除的元素的迭代器
执行此操作时,下一行获取已删除行的索引并打印它(前一个下一行,现在是索引i中的行)。
答案 1 :(得分:1)
这是因为
userDetails.erase(userDetails.begin() + i);
删除包含用户名和密码的用户。
答案 2 :(得分:1)
我不遵循你不理解的内容。但是,我将讨论这段代码,因为它包含一个对初学者来说很常见的严重错误。
for (int i =0; i<userDetails.size(); i++) {
if(userDetails[i].getUserName() == name){
userDetails.erase(userDetails.begin() + i);
}
cout << userDetails[i].getUserName() << " " << userDetails[i].getPassword() << "\n";
}
这个“有效”的原因是当你的程序遇到一个对象,该对象的用户名与输入的用户名相匹配时,你会从向量中删除它。当发生这种情况时,矢量中“擦拭对象的更右侧”的每个对象的索引向下移动一个。因此,假设匹配的名称是“琥珀色”(索引0)。在第一次循环迭代中,将删除琥珀色; janet转移到指数0;克里斯转向指数1;并且gerald转移到索引2.仍然在第一次循环迭代,它将输出索引0,现在是克里斯所以一切都很好。在所有剩余的循环迭代中,userDetails.size()
将评估为新的删除后大小3,因此对于索引0,1,2,您将只获得3次迭代。
现在为BUG:尝试输入“gerald”作为要删除的名称。
如果你这样做,请记住,当i
为3时,它将在循环的第四次迭代中得到处理。杰拉德将被删除,将大小减小到3,最后一个有效索引减少到2.但是此时i
仍为3!所以
cout << userDetails[i].getUserName() << " " << userDetails[i].getPassword() << "\n";
第四次迭代的相当于:
cout << userDetails[3].getUserName() << " " << userDetails[3].getPassword() << "\n";
但没有userDetails[3]
,您的程序应该是段错误。
以下是如何正确实施它:
for (int i =0; i<userDetails.size(); i++) {
if(userDetails[i].getUserName() == name){
userDetails.erase(userDetails.begin() + i);
continue; // skip to next iteration because we can't guarantee 'i' is a valid
// index or that username on this iteration doesn't match
}
cout << userDetails[i].getUserName() << " " << userDetails[i].getPassword() << "\n";
}
但是,我更喜欢以下习语:
auto i = userDetails.begin(), e = userDetails.end();
while (i != e)
{
if (name == i->getUserName())
{
i = userDetails.erase(i); // i is now equal to next element after deleted one
e = userDetails.end(); // update e to be equal to the new end
// don't output because we deleted
}
else
{
std::cout << i->getUserName() << ' ' << i->getPassword() << std::endl;
++i;
}
}