Passing Arguments to function that modifies Vector - Help.

Greetings,

This is my first post here and I'm not even sure how to ask the question as I Know the problem area of my program but not what is wrong.I will include the code. It's for a program to create a deck of cards, shuffle them and then print the shuffled deck. I have marked the problem area(as I see it). It prints only one character of each part of the vector, I need it to print the whole card. Everything works as it should upto the marked point(s).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Card
{
	int face, suit;
	
	static char *faces[];
	static char *suits[];

public:

	Card(int, int);
	
	char* toString(int a,int b)
	{
		//cout << getFaces(getFaceCard()) << " of " << getSuits(getCardSuit()) << "\n\n"; //For Test Purposes
		
		char *FKard = getFaces(getFaceCard());
		char *SKard = getSuits(getCardSuit());
		int n;
		static char buffer[14];
		n = sprintf(buffer,"%s of %s", FKard,SKard);
		//printf("%s <-------\n",buffer); //for test purposes
		//cout << buffer << endl; //test purposes
		return (buffer);
	};

	
	int getFaceCard()
	{
		return face;
	}

	int getCardSuit()
	{
		return suit;
	}
	
	static char*getFaces(int a)
	{
	char*CFaces = new char[15];
	CFaces = (faces[a]);
	return CFaces;
	}
	static char*getSuits(int b)
	{
		char*CSuits = new char[5];
		CSuits = (suits[b]);
		return CSuits;
	}
	friend class DeckOfCards;



};

class DeckOfCards
{ 
	vector<char> Deck;

	int currentCard;

public:
	DeckOfCards(char buffer) //------problem function
	{
		Deck.push_back(buffer);
		shuffle();

		for (vector<char>::iterator i = Deck.begin(); i != Deck.end(); i++)
		{
			cout << *i <<endl;
		}
	}

	void shuffle()
	{
		random_shuffle(Deck.begin(),Deck.end());
	}

	char dealCard()
	{
	}

	bool moreCards()
	{
	}


};

char *Card::faces[] = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
char *Card::suits[] = { "Clubs", "Hearts", "Diamonds", "Spades" };

Card::Card(int a, int b)
{
	face = a;
	suit = b;
}






int _tmain(int argc, _TCHAR* argv[])
{
	
	
	for (int i = 0; i < 13; i++)
	{
		for (int j = 0; j < 4; j++)
		{
		Card kard(i,j);
		char *moo = (kard.toString(kard.getFaceCard(),kard.getCardSuit()));
		//cout << moo << endl; // for test purposes
		DeckOfCards DoC(moo[i]); //<-------problem is here
		}
	}

	cout <<endl<< "^^^^^^^^^^^^^^^^^^"<< endl;
	cout << " "<< endl;

	

	system("pause");
	return 0;
}
You use char far too much. Why do your decks have vectors of chars when you have a Card class?

And eh, this:
1
2
3
4
5
6
static char*getFaces(int a)
{
  char*CFaces = new char[15];
  CFaces = (faces[a]);
  return CFaces;
}


You use char arrays as if they were strings, which you can't. All that code does is to introduce a memory leak.
The correct version is:

1
2
3
4
static string getFace(int index)
{
  return faces[index];
}
Last edited on
Why do your decks have vectors of chars when you have a Card class?


Cause I'm a nub. I've been programming in C++ for a couple weeks..

I couldn't figure out how to get the vector of Card to work properly either.

I'll try and make the changes you suggest. At any rate, is there a way to make it work as I have it?
MidnightRyder RL wrote:
At any rate, is there a way to make it work as I have it?

No, not really. Unless you assign each of the 52 cards a unique character, which would be pointless.
A deck consists of cards, not characters. So you need to make that change.

MidnightRyder RL wrote:
I couldn't figure out how to get the vector of Card to work properly either.

Well, we can help with that if you explain your problem.

Edit: Ah, I see that you were probably trying to store the C strings returned by toString in your deck.
Before you continue with this project, you need to do some reading on std::string and then banish all use of char arrays from your project (save for the faces and suits arrays - those would be acceptable if you made them arrays of const char*).
Aside from the chapter about std::string in your book, the reference (and the examples) are a good starting point:
http://www.cplusplus.com/reference/string/string/

Edit2:
There's more: toString should return the card it is called for, there are no parameters needed.
Functions that don't modify the object should be declared const (toString, getFaceCard, etc.)
For initializing members of a class, the initializer list should be used.
To illustrate, a fixed version could look somewhat like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

class Card
{
  public:
    Card(int face,int suit) : face(face), suit(suit) {}

    string toString() const
    {
      return getFaceName(getFace())+" of "+getSuitName(getSuit());
    }

    int getFace() const {return face;}
    int getSuit() const {return suit;}

  private:
    int face;
    int suit;

    static const char* faces[];
    static const char* suits[];
    static string getSuitName(int index) {return suits[index];}
    static string getFaceName(int index) {return faces[index];}

};

class CardDeck
{
  public:
    CardDeck(Card initialCard)
    {
      deck.push_back(initialCard);
      shuffle();

      for (vector<Card>::iterator it=deck.begin();it!=deck.end();++it)
      {
        cout << it->toString() << endl;
      }
    }

    void shuffle()
    {
      random_shuffle(deck.begin(),deck.end());
    }

  private:
    vector<Card> deck;
};

const char* Card::faces[] = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
const char* Card::suits[] = { "Clubs", "Hearts", "Diamonds", "Spades" };



int main(int argc,char** argv)
{
  for (int i=0;i<13;i++)
  {
    for (int j=0;j<4;j++)
    {
      CardDeck deck(Card(i,j));
    }
  }

  cout << endl << "^^^^^^^^^^^^^^^^^^" << endl;
  cout << " " << endl;
}


Another change that would make sense is to use enums for the suits and faces.
Last edited on
I've reworked this a bit but now the cards don't print out like they did before. It's back down to just the one class. I'm not even gonna look at the other until this works.. The way I had this before it would print all 52 cards in order at this point but since changing to working with string instead of char I only get one character per card of 52 cards..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Card
{
	int face, suit;
	
	static string faces[];
	static string suits[];

public:

	Card(int, int);
	
	string toString()
	{
				
		 string FKard = getFaces(getFaceCard());
		 string SKard = getSuits(getCardSuit());
		 string ofVar = " of ";
		 ofVar+= SKard;
		 FKard+= ofVar;
		 string finalKard;
		 finalKard = FKard;

		 return finalKard;
	};

	
	int getFaceCard()
	{
		return face;
	}

	int getCardSuit()
	{
		return suit;
	}
	
	static string getFaces(int a)
	{
	return faces[a];
	}

	static  string getSuits(int b)
	{
		return suits[b];
	}
	friend class DeckOfCards;



};



 string Card::faces[] = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
 string Card::suits[] = { "Clubs", "Hearts", "Diamonds", "Spades" };

Card::Card(int a, int b)
{
	face = a;
	suit = b;
}

int _tmain(int argc, _TCHAR* argv[])
{
	
	
	for (int i = 0; i < 13; i++)
	{
		for (int j = 0; j < 4; j++)
		{
		Card kard(i,j);
		string moo = (kard.toString());
		cout << moo[i] << endl; // for test purposes  
		
		}
	}

	cout <<endl<< "^^^^^^^^^^^^^^^^^^"<< endl;
	cout << " "<< endl;

	

	system("pause");
	return 0;
}


If everything is correct for the class then I'm guessing it is

cout << moo[i] <<endl; that is the issue.

I can see this only doing the 'i'th element of 'moo' so how do I fix that?

EDIT#1

I fixed that: moo.data() did the trick.

Now I'm looking over your edits. Btw, Thank you very much for assisting me. I greatly appreciate it.
Last edited on
No need for calling data(). cout << moo << endl; is sufficient.
If I take that off I get an error however..?

No operator "<<" matches these operands

Make sure that you have included <string>.
Oh. Thanks.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

class Card
{
	int face, suit;
	
	static string faces[];
	static string suits[];

public:

	Card(int, int);
	
	string toString()
	{
				
		 string FKard = getFaces(getFaceCard());
		 string SKard = getSuits(getCardSuit());
		 string ofVar = " of ";
		 ofVar+= SKard;
		 FKard+= ofVar;
		 string finalKard;
		 finalKard = FKard;

		 return finalKard;
	};

	
	int getFaceCard()
	{
		return face;
	}

	int getCardSuit()
	{
		return suit;
	}
	
	static string getFaces(int a)
	{
	return faces[a];
	}

	static  string getSuits(int b)
	{
		return suits[b];
	}
	friend class DeckOfCards;

};


class DeckOfCards
{
	vector<Card> deck;

public:
	DeckOfCards(Card starter)
	{
		deck.push_back(starter);
		
		
	}

	void shuffle()
	{
		random_shuffle(deck.begin(),deck.end());
	}

	void dealCards()
	{
		for (vector<Card>::iterator i=deck.begin(); i!=deck.end(); ++i)
		{
			cout << i->toString() << endl;
		}
	}

};



 string Card::faces[] = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };
 string Card::suits[] = { "Clubs", "Hearts", "Diamonds", "Spades" };

Card::Card(int a, int b)
{
	face = a;
	suit = b;
}

int _tmain(int argc, _TCHAR* argv[])
{
	
	
	for (int i = 0; i < 13; i++)
	{
		for (int j = 0; j < 4; j++)
		{
		DeckOfCards deck(Card (i,j));
		deck.shuffle();
		deck.dealCards();
				
		}
	}

	cout <<endl<< "^^^^^^^^^^^^^^^^^^"<< endl;
	cout << " "<< endl;

	

	system("pause");
	return 0;
}


Another nub question: My Shuffle isn't working. Did I implement that properly?

I'm looking at http://www.cplusplus.com/reference/algorithm/random_shuffle/ and as far as I can tell it is right..the only thing I can add is a rand parameter. It isn't needed according to the reference but I'm missing something.
Well. You're creating 52 decks with one card each. If you just have one card, there's nothing to shuffle.
Got it. Thank you for all your help.
Topic archived. No new replies allowed.