Why Are These Strings Garbage (Though The Addresses Are Correct)?

Note in the output below that the values printed upon the return from dealPokerHand() are all "╕V┐". And as you can see, the syntax used for both the before and after output statements is the same. Any ideas as to why one produces valid text and the other produces garbage?

The general question was: What is the syntax for passing an array of strings by reference to a function such that modifications to the strings in the called function are reflected in the calling function?

// ---------------------------------------------------------------------------

// shuffleAndDeal.cpp - Card shuffling and dealing program.
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using std::cout;
using std::endl;
using std::left;
using std::right;
using std::setw;
using std::rand;
using std::srand;
using std::time;

void shuffle(); // shuffle function prototype
void dealPokerHand( char *[] ); // deal poker hand function prototype

int deck[ 4 ][ 13 ]; // represents deck of cards

int main()
{
char *pHand[ 5 ] = { "test hand card no 1", "test hand card no 2", "test hand card no 3", "test hand card no 4", "test hand card no 5" }; // pointer to char array for five-card poker hand
srand( time( 0 ) ); // seed random number generator

for ( int i = 0; i < 5; i++ )
cout << "In main(), before call to dealPokerHand, poker hand ( *( pHand + " << i << " ) ) card " << i << " is \"" << *( pHand + i ) << "\", address: \"" << pHand + i << "\"." << endl;


shuffle(); // shuffle the cards in the deck
dealPokerHand( pHand ); // deal a poker hand from the cards in the deck

for ( int i = 0; i < 5; i++ )
cout << "In main(), back from dealPokerHand, poker hand ( *( pHand + " << i << " ) ) card " << i << " is \"" << *( pHand + i ) << "\", address: \"" << ( pHand + i ) << "\"." << endl;

return 0; // indicates successful termination
} // end function main

void shuffle()
{
int row; // represents suit value of card
int column; // represents face value of card

// for each of the 52 cards, choose a slot of the deck randomly
for ( int card = 1; card <= 52; card++ )
{
do // choose a new random location until unoccupied slot is found
{
row = rand() % 4; // randomly select the row
column = rand() % 13; // randomly select the column
} while( deck[ row ][ column ] != 0 ); // end do...while

// place card number in chosen slot of deck
deck[ row ][ column ] = card;
} // end for
} // end function shuffle

// deal a five-card poker hand from cards in deck
void dealPokerHand( char *pokerHand[] )
{
// test
cout << "<<<test>>> pokerHand[ 0 ] is \"" << pokerHand[ 0 ] << "\".\n";
// temp string
char tmpStr[ 20 ];

// initialize suit array
static const char *suit[ 4 ] =
{ "Hearts", "Diamonds", "Clubs", "Spades" };

// initialize face card array
static const char *face[ 13 ] =
{ "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King" };

// for each of the 5 cards in the poker hand
for ( int card = 1; card <= 5; card++ )
{
// loop through rows of deck
for ( int row = 0; row <= 3; row++ )
{
// loop through columns of deck for current row
for ( int column = 0; column <= 12; column++ )
{
// if slot contains current card, display card and save it to the poker hand
if ( deck[ row ][ column ] == card )
{
strcpy_s( tmpStr, face[ column ] );
strcat_s( tmpStr, " of " );
strcat_s( tmpStr, suit[ row ] );
*( pokerHand + card - 1 ) = tmpStr ;
cout << "In dealPokerHand fcn, pokerHand[ " << card - 1 << " ] = \"" << pokerHand[ card - 1 ] << "\", address: \"" << &pokerHand[ card - 1 ] << "\"\n";
} // end if
} // end innermost for
} // end inner for
} // end outer for
} // end function dealPokerHand


// ---------------------------------------------------------------------------

// Output:

In main(), before call to dealPokerHand, poker hand ( *( pHand + i ) ) card 0 is "test hand card no 1", address: "001FF8FC".
In main(), before call to dealPokerHand, poker hand ( *( pHand + i ) ) card 1 is "test hand card no 2", address: "001FF900".
In main(), before call to dealPokerHand, poker hand ( *( pHand + i ) ) card 2 is "test hand card no 3", address: "001FF904".
In main(), before call to dealPokerHand, poker hand ( *( pHand + i ) ) card 3 is "test hand card no 4", address: "001FF908".
In main(), before call to dealPokerHand, poker hand ( *( pHand + i ) ) card 4 is "test hand card no 5", address: "001FF90C".
<<<test>>> pokerHand[ 0 ] is "test hand card no 1".
In dealPokerHand fcn, pokerHand[ 0 ] = "Six of Hearts", address: "001FF8FC"
In dealPokerHand fcn, pokerHand[ 1 ] = "Eight of Clubs", address: "001FF900"
In dealPokerHand fcn, pokerHand[ 2 ] = "King of Spades", address: "001FF904"
In dealPokerHand fcn, pokerHand[ 3 ] = "Ace of Diamonds", address: "001FF908"
In dealPokerHand fcn, pokerHand[ 4 ] = "Deuce of Diamonds", address: "001FF90C"
In main(), back from dealPokerHand, poker hand ( *( pHand + i ) ) card 0 is "╕V┐", address: "001FF8FC".
In main(), back from dealPokerHand, poker hand ( *( pHand + i ) ) card 1 is "╕V┐", address: "001FF900".
In main(), back from dealPokerHand, poker hand ( *( pHand + i ) ) card 2 is "╕V┐", address: "001FF904".
In main(), back from dealPokerHand, poker hand ( *( pHand + i ) ) card 3 is "╕V┐", address: "001FF908".
In main(), back from dealPokerHand, poker hand ( *( pHand + i ) ) card 4 is "╕V┐", address: "001FF90C".

Press any key to continue . . .




Reposting with code tags and indentation so it's actually legible:

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
// ---------------------------------------------------------------------------

// shuffleAndDeal.cpp - Card shuffling and dealing program.
#include <iostream>
#include <iomanip>
#include <cstdlib> 
#include <ctime> 
using std::cout;
using std::endl;
using std::left;
using std::right;
using std::setw;
using std::rand;
using std::srand;
using std::time;

void shuffle(); // shuffle function prototype
void dealPokerHand( char *[] ); // deal poker hand function prototype

int deck[ 4 ][ 13 ]; // represents deck of cards

int main()
{
    char *pHand[ 5 ] = { "test hand card no 1", "test hand card no 2", "test hand card no 3",
                         "test hand card no 4", "test hand card no 5" }; // pointer to char array for five-card poker hand
    srand( time( 0 ) ); // seed random number generator

    for ( int i = 0; i < 5; i++ )
        cout << "In main(), before call to dealPokerHand, poker hand ( *( pHand + " << i << " ) ) card " << i
             << " is \"" << *( pHand + i ) << "\", address: \"" << pHand + i << "\"." << endl;


    shuffle(); // shuffle the cards in the deck
    dealPokerHand( pHand ); // deal a poker hand from the cards in the deck

    for ( int i = 0; i < 5; i++ )
        cout << "In main(), back from dealPokerHand, poker hand ( *( pHand + " << i << " ) ) card " << i
             << " is \"" << *( pHand + i ) << "\", address: \"" << ( pHand + i ) << "\"." << endl;

    return 0; // indicates successful termination
} // end function main

void shuffle()
{
    int row; // represents suit value of card
    int column; // represents face value of card

    // for each of the 52 cards, choose a slot of the deck randomly
    for ( int card = 1; card <= 52; card++ )
    {
        do // choose a new random location until unoccupied slot is found
        {
            row = rand() % 4; // randomly select the row
            column = rand() % 13; // randomly select the column
        } while( deck[ row ][ column ] != 0 ); // end do...while

        // place card number in chosen slot of deck
        deck[ row ][ column ] = card;
    } // end for
} // end function shuffle

// deal a five-card poker hand from cards in deck
void dealPokerHand( char *pokerHand[] )
{
    // test
    cout << "<<<test>>> pokerHand[ 0 ] is \"" << pokerHand[ 0 ] << "\".\n";
    // temp string
    char tmpStr[ 20 ];

    // initialize suit array
    static const char *suit[ 4 ] =
      { "Hearts", "Diamonds", "Clubs", "Spades" };

    // initialize face card array
    static const char *face[ 13 ] =
      { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
        "Eight", "Nine", "Ten", "Jack", "Queen", "King" };

    // for each of the 5 cards in the poker hand
    for ( int card = 1; card <= 5; card++ )
    {
        // loop through rows of deck
        for ( int row = 0; row <= 3; row++ )
        {
            // loop through columns of deck for current row
            for ( int column = 0; column <= 12; column++ )
            {
                // if slot contains current card, display card and save it to the poker hand
                if ( deck[ row ][ column ] == card )
                {
                    strcpy_s( tmpStr, face[ column ] );
                    strcat_s( tmpStr, " of " );
                    strcat_s( tmpStr, suit[ row ] );
                    *( pokerHand + card - 1 ) = tmpStr ;
                    cout << "In dealPokerHand fcn, pokerHand[ " << card - 1 << " ] = \"" << pokerHand[ card - 1 ]
                         << "\", address: \"" << &pokerHand[ card - 1 ] << "\"\n";
                } // end if
            } // end innermost for
        } // end inner for
    } // end outer for
} // end function dealPokerHand 


I'll take a closer look in a bit when I have more time...
Please use [code] tags.

Your problem is because you are misusing arrays.

You cannot say:
1
2
3
char s[] = "Hello world!";

s = "Greetings, earthlings!";

You are attempting to do just that.

Likewise, you are using constants as variables. You hand should technically be typed as:
const char *pHand[ 5 ]
...but, don't do that anyway. You want to be able to overwrite the data, so you need to provide variable space for it.

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
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <ctime>
using namespace std;

void shuffle(); // shuffle function prototype

void dealPokerHand( char[ 5 ][ 50 ] ); // deal poker hand function prototype

int deck[ 4 ][ 13 ]; // represents deck of cards

int main()
{
  char pHand[ 5 ][ 50 ];
  strcpy( pHand[ 0 ], "test hand card no 1" );
  strcpy( pHand[ 2 ], "test hand card no 2" );
  strcpy( pHand[ 3 ], "test hand card no 3" );
  strcpy( pHand[ 4 ], "test hand card no 4" );
  strcpy( pHand[ 5 ], "test hand card no 5" );

  srand( time( 0 ) ); // seed random number generator

  for ( int i = 0; i < 5; i++ )
    cout << "In main(), before call to dealPokerHand, poker hand ( *( pHand + " << i << " ) ) card " << i << " is \"" << *( pHand + i ) << "\", address: \"" << pHand + i << "\"." << endl;


  shuffle(); // shuffle the cards in the deck
  dealPokerHand( pHand ); // deal a poker hand from the cards in the deck

  for ( int i = 0; i < 5; i++ )
    cout << "In main(), back from dealPokerHand, poker hand ( *( pHand + " << i << " ) ) card " << i << " is \"" << *( pHand + i ) << "\", address: \"" << ( pHand + i ) << "\"." << endl;

  return 0; // indicates successful termination
} // end function main

void shuffle()
{
  int row; // represents suit value of card
  int column; // represents face value of card

  // for each of the 52 cards, choose a slot of the deck randomly
  for ( int card = 1; card <= 52; card++ )
    {
    do // choose a new random location until unoccupied slot is found
      {
      row = rand() % 4; // randomly select the row
      column = rand() % 13; // randomly select the column
      } while( deck[ row ][ column ] != 0 ); // end do...while

    // place card number in chosen slot of deck
    deck[ row ][ column ] = card;
    } // end for
} // end function shuffle

// deal a five-card poker hand from cards in deck
void dealPokerHand( char pokerHand[ 5 ][ 50 ] )
{
  // test
  cout << "<<<test>>> pokerHand[ 0 ] is \"" << pokerHand[ 0 ] << "\".\n";
  // temp string
  char tmpStr[ 20 ];

  // initialize suit array
  static const char *suit[ 4 ] =
    { "Hearts", "Diamonds", "Clubs", "Spades" };

  // initialize face card array
  static const char *face[ 13 ] =
    { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
    "Eight", "Nine", "Ten", "Jack", "Queen", "King" };

  // for each of the 5 cards in the poker hand
  for ( int card = 1; card <= 5; card++ )
    {
    // loop through rows of deck
    for ( int row = 0; row <= 3; row++ )
      {
      // loop through columns of deck for current row
      for ( int column = 0; column <= 12; column++ )
        {
        // if slot contains current card, display card and save it to the poker hand
        if ( deck[ row ][ column ] == card )
          {
          strcpy( tmpStr, face[ column ] );
          strcat( tmpStr, " of " );
          strcat( tmpStr, suit[ row ] );
          strcpy( pokerHand[ card - 1 ], tmpStr );
          cout << "In dealPokerHand fcn, pokerHand[ " << card - 1 << " ] = \"" << pokerHand[ card - 1 ] << "\", address: \"" << &pokerHand[ card - 1 ] << "\"\n";
          } // end if
        } // end innermost for
      } // end inner for
    } // end outer for
  } // end function dealPokerHand 



Finally, you are missing #include files and using statements. Don't waste time using a zillion things. Just using namespace std;. If you are really concerned about not importing unknown names, then just prefix everything with the proper namespace: std::strcpy, for example.

Oh, and while I'm on strcpy, don't blindly use things like strcpy_s(). If you are using strcpy() (or variations) at all, use it properly and watch your bounds. That's my opinion, however.


I recommend you pick a language: either program in C or program in C++. If you are using C, then dump the C++ stuff. If you are using C++, then forget all the C string handling nonsense and just use the STL string class. It will make your life significantly easier.

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
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef vector <string> tHand;

// prototypes
void shuffle();
void dealPokerHand( tHand& );

ostream& operator << ( ostream& outs, const tHand& hand )
{
  for (unsigned n = 0; n < hand.size(); n++)
    outs << hand[ n ] << "\n";
  return outs;
}

int deck[ 4 ][ 13 ]; // represents deck of cards

int main()
{
  const char* _hand[] = {
    "test hand card no 1",
    "test hand card no 2",
    "test hand card no 3",
    "test hand card no 4",
    "test hand card no 5"
    };
  tHand hand( _hand, _hand + 5 );

  srand( time( 0 ) ); // seed random number generator

  cout << "In main(), before call to dealPokerHand:\n" << hand << endl;


  shuffle(); // shuffle the cards in the deck
  dealPokerHand( hand ); // deal a poker hand from the cards in the deck


  cout << "In main(), after all to dealPokerHand:\n" << hand << endl;

  return 0; // indicates successful termination
} // end function main

void shuffle()
{
  int row; // represents suit value of card
  int column; // represents face value of card

  // for each of the 52 cards, choose a slot of the deck randomly
  for ( int card = 1; card <= 52; card++ )
    {
    do // choose a new random location until unoccupied slot is found
      {
      row = rand() % 4; // randomly select the row
      column = rand() % 13; // randomly select the column
      } while( deck[ row ][ column ] != 0 ); // end do...while

    // place card number in chosen slot of deck
    deck[ row ][ column ] = card;
    } // end for
} // end function shuffle

// deal a five-card poker hand from cards in deck
void dealPokerHand( tHand& pokerHand )
{
  // temp string
  char tmpStr[ 20 ];

  // initialize suit array
  static const char *suit[ 4 ] =
    { "Hearts", "Diamonds", "Clubs", "Spades" };

  // initialize face card array
  static const char *face[ 13 ] =
    { "Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
    "Eight", "Nine", "Ten", "Jack", "Queen", "King" };

  // for each of the 5 cards in the poker hand
  for ( int card = 1; card <= 5; card++ )
    {
    // loop through rows of deck
    for ( int row = 0; row <= 3; row++ )
      {
      // loop through columns of deck for current row
      for ( int column = 0; column <= 12; column++ )
        {
        // if slot contains current card, display card and save it to the poker hand
        if ( deck[ row ][ column ] == card )
          {
          pokerHand[ card - 1 ]  = face[ column ];
          pokerHand[ card - 1 ] += " of ";
          pokerHand[ card - 1 ] += suit[ row ];
          } // end if
        } // end innermost for
      } // end inner for
    } // end outer for
  } // end function dealPokerHand 

There are other things you can do to clean up the code, but that's all you'll get out of me for now... (sorry)

Hope this helps.
Dear Disch and Duoas,

Thanks for your thoughtful reply. I have implemented your suggestions and the problem is now resolved. Kind regards,

David
Topic archived. No new replies allowed.