我在编写练习代码时遇到了一个奇怪的问题。
首先,当我选择第一个选项时,请输入错误的条目。它应该转到我代码的else
分支,但它被卡在那里。我真的不知道为什么。当我输入一个"游戏标题"的空间。
其次,我在删除分支上发表了评论的行:
iter = gameTitles.erase(iter);
...根本不起作用。我要做的是通过输入输入来删除条目,然后将其与条目进行比较之后,以便知道要删除什么。这就是为什么我也使用迭代器。
// Exercise 1
/*
Write a program using vectors and iterators that allows a user to maintain a list of
his or her favorite games. The program should allow the user to list all game titles,
add a game title, and remove a game title.
*/
#include <iostream>
#include <windows.h>
#include <string>
#include <vector>
using namespace std;
int main(){
bool bLoop = true;
int nChoice;
char cChoice;
string sInput;
vector<string>::const_iterator iter;
vector<string> gameTitles;
while(bLoop){
// -Head
cout << "///////////////////////////////////n// My Favorite Gamesnn";
cout << "1. Add titlen2. Delete titlen3. Clear listnn";
// -List
if(!gameTitles.empty()){
for(iter = gameTitles.begin(); iter!=gameTitles.end(); ++iter){
cout << "-" << *iter << endl;
}
}
cout << "n:: ";
cin >> nChoice;
// 1. Add
if(nChoice == 1){
cout << "nGame Title: ";
cin >> sInput;
gameTitles.push_back(sInput);
}
// 2. Delete
else if(nChoice == 2) {
cout << "Delete Title: ";
cin >> sInput;
for(iter = gameTitles.begin(); iter!=gameTitles.end(); ++iter){
if(*iter == sInput){
cout << "erased";
//iter = gameTitles.erase(iter);
}
}
}
// 3. Clear
else if(nChoice == 3){
cout << "Are you sure? (y/n) ";
cin >> cChoice;
if(cChoice == 'y'){
gameTitles.clear();
}
} else {
cout << "nInvalid Choice, Please try again.n";
}
// -Clean
system("PAUSE");
system("cls");
}
}
编辑:解决了第一期。使用了普通的迭代器,而不是常规迭代器
edit2:解决第二期,这是我的更正代码:
// Exercise 1
/*
Write a program using vectors and iterators that allows a user to maintain a list of
his or her favorite games. The program should allow the user to list all game titles,
add a game title, and remove a game title.
*/
#include <iostream>
#include <windows.h>
#include <string>
#include <vector>
using namespace std;
int main(){
bool bLoop = true;
int nChoice;
char cChoice;
string sInput;
vector<string>::iterator iter;
vector<string> gameTitles;
while(bLoop){
// -Head
cout << "///////////////////////////////////n// My Favorite Gamesnn";
cout << "1. Add titlen2. Delete titlen3. Clear listnn";
// -List
if(!gameTitles.empty()){
for(iter = gameTitles.begin(); iter!=gameTitles.end(); ++iter){
cout << "-" << *iter << endl;
}
}
cout << "n:: ";
cin >> nChoice;
if(cin.fail()){
cin.clear();
cin.ignore();
}
// 1. Add
if(nChoice == 1){
cout << "nGame Title: ";
cin >> sInput;
gameTitles.push_back(sInput);
}
// 2. Delete
else if(nChoice == 2) {
cout << "Delete Title: ";
cin >> sInput;
for(iter = gameTitles.begin(); iter!=gameTitles.end(); ){
if(*iter == sInput){
cout << "erased";
iter = gameTitles.erase(iter);
} else {
++iter;
}
}
}
// 3. Clear
else if(nChoice == 3){
cout << "Are you sure? (y/n) ";
cin >> cChoice;
if(cChoice == 'y'){
gameTitles.clear();
}
} else {
cout << "nInvalid Choice, Please try again.n";
}
// -Clean
system("PAUSE");
system("cls");
}
}
实际上有两个问题:
- 如果输入有缺陷的东西,为什么我的输入会卡住?您需要验证使用
if (std::cin >> nChoice) { /* actual processing */ }
之类的输入是否成功。请注意,当输入失败时,nChoice
的值不会更改。如果输入失败,则需要进行一些错误恢复:流已经进入故障状态(即,在错误标志中设置了std::ios_base::failbit
),并且在获得clear()
ED之前不会拒绝进行任何进一步的输入。这仍然在您可能想要ignore()
的输入中留下了令人讨厌的字符。 -
为什么使用
erase()
行为不当的循环?当您实际做erase()
时,您不想在循环结束时再次递增迭代器。如果这样做,它很可能会将迭代器移至最终,从而导致不确定的行为。也就是说,循环应该看起来像这样:for(iter = gameTitles.begin(); iter!=gameTitles.end(); ) { if (*iter == sInput) { cout << "erased"; iter = gameTitles.erase(iter); } else { ++iter; } }
当然,同一逻辑的简短版本是:
gamesTitles.erase(std::remove(gamesTitles.begin(), games.Titles.end(), sInput), games.Titles.end());
我认为您弄错了,从容器的erase
返回的iterator
永远不会指向从该容器中删除的价值,假设以下内容:
std::vector<std::string> v;
// push some items to v
v.push_back( "1" );
v.push_back( "2" );
v.push_back( "3" );
auto i = v.erase( v.end() - 1 );
// Now i point to end of v and you can't derefrence it
相反,它指向以前包含您的值的vector
中的位置:
auto i = v.erase( v.begin() );
assert( *i == "2" );