Fixing C++ Card Class Errors in Visual C++ 6

In summary, the author is working on an assignment and is having some problems with the code. They provide a header file and a class that they have written so far. They also provide a driver that they have written.
  • #1
Math Is Hard
Staff Emeritus
Science Advisor
Gold Member
4,652
38
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:
//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:
//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 by a moderator:
Physics news on Phys.org
  • #2
I also have a simple driver that I'm using:
Code:
#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:
  • #3
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:
  • #4
OMG! You RULE, Hurkyl! Thank you!
 
  • #5
FWIW Borland C++ (an ancient version) let's 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:
 
  • #6
Thanks. I'm sure y'all haven't seen the last of me. I'll be back after I get into more trouble!
 
  • #7
There's something that is confusing me. In my teacher's driver he makes a new card like so:
Code:
                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.
 
  • #8
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;
 
  • #9
OK, thanks. I guess I just haven't seen anything like that before.
 
  • #10
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:
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.
 
  • #11
Math Is Hard said:
I don't have any friends
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.
 
  • #12
Hurkyl said:
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.

:smile: :smile: :smile:
ayeee! I missed that. My eyeballs have gone south!
 
  • #13
rats! I still can't beat this thing into submission.
I wrote the friend function my implementation file like so:
Code:
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:
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'"
 
  • #14
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.
 
  • #15
That was it! Thanks so much!:smile:
 
  • #16
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:
std::ostream& operator<<(std::ostream& os, const Card& c)
{
	os<<c.abbr();
	return os;
}
which called this:
Code:
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.
 
Last edited by a moderator:
  • #17
The Deck header:
Code:
#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:
#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;
 }
}
 
  • #18
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.
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? :-p 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.
 
  • #19
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.
 
  • #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.
 
  • #21
Well, the expression deck[0] is of type Card, right?

(technically, it's of type Card const&, but that's a minor quibble)

Oooh, I understand your problem now. You want to call abbr, but it's inaccessible, meaning you can't accomplish your goal of building one gigantic string.

(technically, you can, in a very roundabout fashion. But let's ignore that too)

So, that just means you'll have to find some way to output cards without calling abbr.
























If only there already existed a function for outputting a card... :rolleyes:
 
  • #22
well, let's see.. the Card class has an overloaded << friend which grabs the abbreviation string from the private member function abbr(), but I have absolutely no idea how to use the << in any other way than cout<< in main(). Instead of printing it with cout<< how can I give it to the os that is returned in my Deck << operator?
 
  • #23
nebbermind. It was easier than I thought.
os<<d.deck[0];
 
  • #24
Yep! :smile:
 
  • #25
*sigh* I'm having trouble getting the deck shuffling function going. I tried making it a friend function.
Code:
//deck.h header
friend void shuffle(const Deck& d);
for the implementation I just tried to replace a card with another to test.
Code:
//in deck.cpp
void shuffle(const Deck& d)
{
	d.deck[1] = d.deck[51];
}
and then I tried making a new card and putting it in the deck
Code:
//in deck.cpp
void shuffle(const Deck& d)
{
	Card::Suit s = Card::CLUB;
	Card::Rank r = Card::TWO;
	Card c(r,s);
	d.deck[1]=c;
}
but for both I get error C2678: binary '=' : no operator defined which takes a left-hand operand of type 'const class pic10b::Card' (or there is no acceptable conversion)

Do I need to overload the = operator in my Card class? Or my Deck class? Both? I'm getting confused because in my Deck constructor I can use =.
Code:
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++;
	  }
     }
}
Thanks. I am tearing my hair out over this %@!#! assignment.:frown:
 
  • #26
The compiler automatically supplies your class with a default implementation of operator=.


Now, the compiler message gives you a big hint -- what sort of arguments would you expect operator= to take here? Is there anything suspicious about the types you actually passed to operator=?
 
  • #27
I'm expecting it to take a card, which it does in the constructor. Why won't it take it in the shuffle function, if the card is an element of the deck?
 
  • #28
Right, you want to assign to a Card object.

But you are assigning to a const Card object. Did you really mean to assign to a Card constant?
 
  • #29
oops!:redface:
 

Related to Fixing C++ Card Class Errors in Visual C++ 6

1. What are some common errors when coding a C++ card class in Visual C++ 6?

Common errors when coding a C++ card class in Visual C++ 6 include syntax errors, such as missing semicolons or brackets, as well as logical errors, such as incorrect use of variables or functions. Other common errors may involve issues with class inheritance or incorrect data types.

2. How can I troubleshoot errors in my C++ card class code in Visual C++ 6?

To troubleshoot errors in your C++ card class code in Visual C++ 6, you can use the built-in debugger to step through your code and identify any specific lines or functions where errors may be occurring. Additionally, reviewing error messages and using resources such as online forums or documentation can help identify and resolve any issues.

3. Can I use external libraries or frameworks when coding a C++ card class in Visual C++ 6?

Yes, it is possible to use external libraries or frameworks when coding a C++ card class in Visual C++ 6. However, you may need to ensure that the external libraries are compatible with the Visual C++ 6 compiler and that you properly link the libraries in your project settings.

4. How can I optimize my C++ card class code in Visual C++ 6 for better performance?

To optimize your C++ card class code in Visual C++ 6 for better performance, you can use techniques such as minimizing memory usage, avoiding unnecessary function calls, and optimizing loops. Additionally, using data structures and algorithms appropriate for your specific card game can also improve performance.

5. Is it possible to create a graphical user interface for my C++ card class in Visual C++ 6?

Yes, it is possible to create a graphical user interface for your C++ card class in Visual C++ 6. You can use the built-in MFC (Microsoft Foundation Classes) to create a GUI for your application, or you can use other external frameworks or libraries specifically designed for creating GUIs in C++.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
918
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
9
Views
2K
  • Programming and Computer Science
3
Replies
75
Views
5K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
5K
  • Programming and Computer Science
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
6
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
9
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
3K
Back
Top