我用C ++制作了这个非常简单的单人纸牌。甲板随机洗牌,我拿一张牌,我按顺序排列Ace,One,Two,......,Ten,Jack,Queen,King。如果卡片正是我发出的信息,我将卡片从卡座中取出。我使用剩余的牌组迭代这个过程,直到我移除牌或直到牌组为空(仅在这种情况下我获胜)。这是我写的代码,但是当我使用函数erase删除卡时,我在第62行出错了。我无法理解哪个是问题。
#include <iostream>
#include <vector>
using namespace std;
enum SUIT { HEART, CLUB, DIAMOND, SPADE };
string suit_string[] = {"HEART", "CLUB", "DIAMOND", "SPADE"};
enum VALUE { ACE, TWO, THREE, FOUR, FIVE, SIX,
SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING};
string value_string[] = {"ACE", "TWO", "THREE", "FOUR", "FIVE",
"SIX", "SEVEN", "EIGHT","NINE", "TEN", "JACK", "QUEEN", "KING"};
class Card {
public:
Card(SUIT s, VALUE v);
SUIT suit;
VALUE value;
string toString();
};
Card::Card(SUIT s, VALUE v){
suit=s;
value=v;
}
string Card::toString(){
return value_string[(int)this->value]+" of "+suit_string[(int)this->suit];
}
int main() {
vector<Card*> deck;
for (int i=0; i<4; i++) {
for (int j=0; j<13; j++) {
deck.push_back(new Card((SUIT)i,(VALUE)j));
}
}
int removed_count, runs = 0;
do{
random_shuffle(deck.begin(),deck.end());
removed_count=0;
cout<<"--- Run number: "<<++runs<<"\n";
cout<<"--- still "<<deck.size()<<" cards in the deck\n";
for (int i=0; i<4; i++) {
for (int j=0; j<13; j++) {
//cout<<i*13+j<<"\n";
int position=i*13+j; //from 0 to 51
cout<<"'"+value_string[j]+"'"<<" <-> ";
Card card=*(deck.at(position));
cout<<card.toString()<<" ";
if(card.value == j){
removed_count++;
deck.erase(deck.begin()+position); //problems here!
cout<<"removed\n";
}else{
cout<<"not removed\n";
}
}
}
if(deck.empty()) break;
}while(removed_count>0);
if(deck.empty()){
cout<<"You win!\n";
}else{
cout<<"You lose!\n";
}
return 0;
}
答案 0 :(得分:4)
好吧,当我启动它时,我得到了
'KING' <-> terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
显然,这意味着您正在尝试访问超出向量范围的内容。您正在删除循环中的元素:
deck.erase(deck.begin()+position);
在点击之后,向量的大小将是51而不是52.但是,你的周期正在处理52个值,正如你在这个评论中清楚地提到的那样:
int position=i*13+j; //from 0 to 51
因此,在删除项目并且牌组中剩下51个项目(0到50)之后,最后一次迭代仍将尝试访问第51个元素并崩溃。失败的实际行是这一行:
Card card=*(deck.at(position));
当状态如下:
正如您所看到的,向量中有51个元素,*(deck.at(position))
将尝试访问第52个元素(因为从零开始计数,该索引为51),并抛出异常。