1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C++ card class errors

  1. Jan 27, 2007 #1

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Hi. I am working on an assignment writing the implementation for a class of playing cards.
    http://www.pic.ucla.edu/~nathan/cgi-bin/moin.cgi/la1#head-111d7fc9df65f327018fa94234ab0b23c0857e98
    Here is the header file that we were provided.
    Code (Text):

    //filename card.h
    #ifndef CARD_H
    #define CARD_H
    #include <iostream>

    namespace pic10b{
            class Card{
                    friend std::ostream& operator<<(std::ostream& os, const Card& c);
            public:
                    enum Rank {TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};
                    enum Suit {CLUB, DIAMOND, HEART, SPADE};
                    Card(){rank = TWO; suit = CLUB;};
                    Card( Rank r, Suit s);
                    Card( const Card& c );
                    Rank getRank() const;
                    Suit getSuit() const;
                    bool isFaceCard() const;
                    std::string toString() const;
                    bool operator<(const Card& c) const;
                    bool operator>(const Card& c) const;
                    bool operator<=(const Card& c) const;
                    bool operator>=(const Card& c) const;
                    bool operator==(const Card& c) const;
                    bool operator!=(const Card& c) const;
            private:
                    std::string abbr() const;
                    Rank rank;      
                    Suit suit;
            };

    }
    #endif
     
    I have written two constructors and the getRank() and getSuit() member functions so far.
    Code (Text):

    //filename card.cpp
    #include "card.h"
    using namespace pic10b;
    using namespace std;

    Card::Card(Rank r, Suit s)
    {
        rank = r;
        suit = s;
    }
                   

    Card::Card(const Card& c )
    {
        rank = c.getRank();
        suit = c.getSuit();
    }

               
    Rank Card::getRank() const  //errors reference this line
    {
        return rank;
    }
                 
    Suit Card::getSuit() const
    {
        return suit;
    }
     
    I am working in Visual C++ 6 and getting some errors:
    error C2143: syntax error : missing ';' before 'tag::id'
    error C2501: 'Rank' : missing storage-class or type specifiers
    fatal error C1004: unexpected end of file found

    and all reference the
    Rank Card::getRank() const
    line in my card.cpp file.
    Am I missing something obvious? Thanks!
     
    Last edited: Jan 27, 2007
  2. jcsd
  3. Jan 27, 2007 #2

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    I also have a simple driver that I'm using:
    Code (Text):

    #include<iostream>
    #include "card.h"
    #include<string>
    #include<cstdlib>

    using namespace pic10b;
    using namespace std;

    int main()
    {        
            return 0;
    }
     
    just a stripped down version of my prof's to provide a main() function.
     
    Last edited: Jan 27, 2007
  4. Jan 27, 2007 #3

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    The problem is that the full name of that type is Card::Rank.

    In the declaration Rank Card::getRank() const, you are not yet within the scope of Card when you are declaring the return type... so you have to fully qualify it as Card::Rank.


    Actually, I fibbed slightly. The full name is pic10b::Card::Rank. But I guess that using directive means that you don't have to specify the pic10b:: there.


    Oh, and as a plug for gcc, it figured out that you were trying to name a type (MSVC++ thought you were trying to declare a variable named Rank) and it emits the error:

    error: `Rank' does not name a type
     
    Last edited: Jan 27, 2007
  5. Jan 27, 2007 #4

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    OMG! You RULE, Hurkyl! Thank you!!!!!!!!!!
     
  6. Jan 27, 2007 #5

    AlephZero

    User Avatar
    Science Advisor
    Homework Helper

    FWIW Borland C++ (an ancient version) lets this through with a warning:

    Warning card.cpp 20: Use qualified name to access member type 'pic10b::Card::Rank'
    Warning card.cpp 25: Use qualified name to access member type 'pic10b::Card::Suit'

    Line 20 was your
    Rank Card::getRank() const //errors reference this line

    But we already knew CPP compilers are not written so that mortals can understand the error messages. Tell me something new... :rolleyes:
     
  7. Jan 27, 2007 #6

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Thanks. I'm sure y'all haven't seen the last of me. I'll be back after I get into more trouble!
     
  8. Jan 27, 2007 #7

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    There's something that is confusing me. In my teacher's driver he makes a new card like so:
    Code (Text):

                    int r = rand()%13;
                    int s = rand()%4;
                    cout << "Round " << i+1 <<": Drawing first random card...";
                    Card::Suit S = Card::Suit(s);
                    Card::Rank R = Card::Rank(r);
                    Card c1(R, S);
                    cout << "it's a " << c1.toString() << endl;
     
    I don't really understand how Suit(s) works in
    Card::Suit S = Card::Suit(s);
    since Suit is a member variable and not a function. The parentheses confuse me.
    I'm not clear on how it takes an int value and casts it as a Suit enum type. Is this just something you can do with enums?
    Same question for Rank(r) of course.
     
  9. Jan 27, 2007 #8

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Card::Suit isn't a variable, it's a type... and you're invoking one of its constructors.


    Try out this piece of code:

    std::cout << char(65) << std::endl;
     
  10. Jan 27, 2007 #9

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    OK, thanks. I guess I just haven't seen anything like that before.
     
  11. Jan 27, 2007 #10

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    One last thing I am stuck on. He has this private member function that returns a string that is an abbreviation of the card.
    If card c1 is a King of Clubs, the programmer can just do
    cout << c1;
    in main() and it will print "KC"
    In the header, the function declaration looks like this:
    Code (Text):

    private:
                    std::string abbr() const;
     
    I can't figure out how cout<< would know what to do, or how to implement this. Any hints?

    I don't have any friends, so I figure it has to be one the member functions that calls it, but I don't know which one.
     
  12. Jan 27, 2007 #11

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Such is the life of a computer programmer. :cry:

    Er, actually you do:

    friend std::eek:stream& operator<<(std::eek:stream& os, const Card& c);

    So if you write that function, it will be able to access the abbr() method.
     
  13. Jan 27, 2007 #12

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    :rofl: :rofl: :rofl:
    ayeee! I missed that. My eyeballs have gone south!
     
  14. Jan 28, 2007 #13

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    rats! I still can't beat this thing into submission.
    I wrote the friend function my implementation file like so:
    Code (Text):
    std::ostream& operator<<(std::ostream& os, const Card& c)
    {
        os<<c.abbr();
        return os;
    }
     
    and then wrote the abbr() private member function like this, just to test:
    Code (Text):

    std::string Card::abbr() const
    {
        string str = "KC";
        return str;
    }
     
    but I'm getting an error "error C2248: 'abbr' : cannot access private member declared in class 'pic10b::Card'"
     
  15. Jan 28, 2007 #14

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    I have a guess, haven't tested it yet, though.


    Your class specified ::pic10b::eek:perator<< as its friend, but you wrote ::eek:perator<<. You need to write that function in the pic10b namespace, not the global namespace.
     
  16. Jan 28, 2007 #15

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    That was it!! Thanks so much!!!!:smile:
     
  17. Feb 2, 2007 #16

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    For the next assignment, we are writing a Deck class which uses the Card class we created. I wrote the default constructor, but I am stuck on overloading the << to cout a deck, which is an array of 52 cards.
    The assignment is here:
    http://www.pic.ucla.edu/~nathan/cgi-bin/moin.cgi/sa5
    I figure for every position in the array I need to get the card that's there to return it's string abbreviation. I think I need to loop and grab strings and concatenate into one long string to finally put into os (I think!!!) but I can't figure out how to do this.

    When we overloaded the "<<" just to cout<< a single card I used this:
    Code (Text):
    std::ostream& operator<<(std::ostream& os, const Card& c)
    {
        os<<c.abbr();
        return os;
    }
    which called this:
    Code (Text):

    std::string Card::abbr() const
    {
     //this just returned a 2-letter string for
    //the card abbreviation based on
    //the enums for the rank and suit.
    }
     
    so I can't figure out how to get each abbreviation from the cards in the deck. Any thoughts? Thanks. All I have now is a modified version of the card << overloader for a test.

    I'll put what I have below in the next post.
     
  18. Feb 2, 2007 #17

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    The Deck header:
    Code (Text):
    #ifndef DECK_H
    #define DECK_H
    #include <iostream>
    #include "card.h"
    namespace pic10b{
            class Deck{
      public:
       Deck(); // constructor  
      friend std::ostream& operator<<(std::ostream& os, const Deck& d);
      private:
       Card deck[52];
      };
    }
    #endif
     
    The deck.cpp
    Code (Text):
    #include "card.h"
    #include "deck.h"
    #include <sstream>
    #include <string>
    using namespace pic10b;
    using namespace std;

    namespace pic10b{
    Deck::Deck() // constructor
    {      
    int i = 0;

        for(Card::Suit s = Card::CLUB; s < Card::SPADE; s++)
        {
            for(Card::Rank r = Card::TWO; r < Card::ACE; r++)
            {
            Card c(r,s);
            deck[i] = c;
            i++;
            }
        }

    }


    std::ostream& operator<<(std::ostream& os, const Deck& d)
     { 
         os<<"Test";
         return os;
     }
    }
     
     
  19. Feb 3, 2007 #18

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    How about starting with an empty string and writing a loop where you grab strings and append them to your string, and then put it in os? :tongue: I don't know what part with which you're having trouble.

    Incidentally, you can write to a stream as many times as you like; there's no need to do it with a single insertion.
     
  20. Feb 3, 2007 #19

    Math Is Hard

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Hi Hurkyl, Sorry for not being more specific. What I can't figure out is how to return a string value out of a card that's in the deck. I can reference d[0] for the first card in the deck, but I am not sure what to do from there.
     
  21. Feb 3, 2007 #20
    IF your card value and card suit are members of the class...it should be easy...just return a string or a char[2] or a char*...note a returning variables does not always have ot e on the left side it could be in your parameter list.

    ...if they are not inputed you will require to pas sthe suit and value.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: C++ card class errors
Loading...