Question

Been at this one for a while now, would appreciate some help.

I'm to create and object Card with enum values Rank and Suit based on a string input. The string will be in the format of '2C, AD' etc. for TWO CLUBS and ACE DIAMONDS respectively.

I tried using a linear search function I found elsewhere on StackOverflow, it's in there but it just returns -1 because it doesn't seem to be getting the right type of input.

I've been able to convert the other way using a char * array, but can't for the life of me do the opposite way around. See below for implementation:

Card.h

#ifndef _card_h
#define _card_h

#include <string>
#include <iostream>

using namespace std;


enum Rank{  TWO, THREE, FOUR, FIVE, SIX, SEVEN,
            EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};


enum Suit{  CLUBS, DIAMONDS, HEARTS, SPADES};

//Character sets used to convert enums to strings
static const char * RankStrings[] = { "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A",};
static const char * SuitStrings[] = { "C", "D", "H", "S" };

class Card {

public:

    ///Constructors and destructors
    Card();
    ~Card();

    ///Accessors
    Rank getRank();
    Suit getSuit();
    string getSuitString();
    string toString(); ///No longer used, but left for testing
    int linearSearch(const char**, const char*, int);

    ///Mutators
    Card(Rank rank, Suit suit);
    Card(string cardStr);


    ///Operators
    bool operator()(Card*, Card*);
    friend ostream& operator<<(ostream&, Card&);

private:
    Suit suit;
    Rank rank;
};

#endif // _random_h

Card.cpp

#include "card.h"
#include <string>
#include <stdlib.h>
#include <cstring>
#include <iostream>
#include <sstream>
using namespace std;

/**CONSTRUCTORS*/
///Noarg constructor that sets default card values
Card::Card(){
    suit = CLUBS;
    rank = TWO;
}

Card::~Card(){} //Destructor

/**ACCESSORS*/
Rank Card::getRank(void){
    return rank;
}

Suit Card::getSuit(void){
    return suit;
}

string Card::getSuitString(){
    return SuitStrings[suit];
}

/**From tutorial, was used during testing but has been reimplemented
 * as an overloaded operator<< below
 */
string Card::toString(){

    string cardValues;

    cardValues += RankStrings[rank];
    cardValues += SuitStrings[suit];

    return cardValues;
}

/**MUTATORS*/
///Create a new card with given Rank and Suit
Card::Card(Rank cardRank, Suit cardSuit){
    rank = cardRank;
    suit = cardSuit;
}

int Card::linearSearch (const char **Array, const char *searchKey, int arraySize) {
    for (int i = 0; i < arraySize; ++i) {
        if (strcmp(Array[i], searchKey) == 0)
            return i;
    }

    // We didn't find the searchKey in the Array
    return -1;
}

///Sets card rank and suit based on string input
Card::Card(string cardStr){
    stringstream ss;
    string rankStr;

    char *c = &cardStr.at(0);
    cout << *c << endl; //This prints correct value but doesnt work in method below

    int index = linearSearch(RankStrings, c, 13);
    cout << index << endl;


}



/**OPERATORS*/
///Functor to compare two cards for their value
bool Card::operator()(Card* card1, Card* card2){
    return card1->getRank() > card2->getRank();
}

///Puts a string representation of input card on the output stream
ostream& operator<<(ostream& out, Card& card){
    out << RankStrings[card.rank] << SuitStrings[card.suit];
    return out;
}
Était-ce utile?

La solution

The problem is you are taking the address of the '2' in "2C" and then using it as if it is a complete C string. Then when you use strcmp in linearSearch it is trying to match the whole string ("2C") and fails.

One way to get around this is to change your SuitStrings or RankStrings to char instead of char *, but that would involve changing your other methods as well.

Another way is to copy the char you are working with into a seperate one character string so that strcmp will work. something like this should do it:

char rankStr[2];
rankStr[0] = cardStr[0];
rankStr[1] = '\0'; // NULL terminated.

int index = linearSearch(RankStrings, rankStr, 13);

Yet another way is to change linearSearch to just look at the first character of both strings.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top