I got this strange problem while writing code for an exercise.
First when I pick the first option, enter a faulty entry. It’s supposed to go to an else branch of my code but instead it gets stuck in there. I really don’t know why. This also happens when I enter a “game title” with a space in between.
Secondly the line I commented out at the delete branch:
iter = gameTitles.erase(iter);
… doesn’t work at all. What I’m trying to do is deleting an entry by typing it out and after that comparing it to an entry so it knows what to delete. That’s why I’m also using the iterator.
// 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 Games\n\n";
cout << "1. Add title\n2. Delete title\n3. Clear list\n\n";
// -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");
}
}
EDIT: Solved first issue. Used a normal iterator instead of a constant one
EDIT2: Solved second issue, here is my corrected code:
// 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 Games\n\n";
cout << "1. Add title\n2. Delete title\n3. Clear list\n\n";
// -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");
}
}
There are actually two questions:
if (std::cin >> nChoice) { /* actual processing */ }. Note that the value ofnChoicewon’t change when the input fails. If the input failed, you need to do some error recovery: The stream has gone into fail state (i.e.,std::ios_base::failbitis set in the error flags) and won’t refuse to do any further input until it gotclear()ed. This still leaves the offending character(s) in the input which you may want toignore().Why is the loop using
erase()misbehaving? When you actually doerase()a value you don’t want to increment the iterator again at the end of the loop. If you do, it may very well move the iterator beyond the end resulting in undefined behavior. That is, the loop should look something like this:Of course, a short version of the same logic is this: