Arcticp
Arcticp

Reputation: 3

C, A random element in array becomes a '?' char when printing to terminal

I am trying to shuffle a array of Card structures and print them to the screen. The shuffle works fine, however when printing the array to the screen, exactly one object displays as a '?' char. It is a different object each time. Without shuffling, this is the output:

$./shuffle
2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH AH 
2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC AC 
2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD AD 
2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS AS

Here are some of the outputs from the terminal when I run the program with shuffling:

$./shuffle
6S 8C 7H 9H 5S 7S 4H 9C 9D AH 4S TD 4C 
JC 8D KH 5D JD 7D 7C 3D 2S 4D QH 3C TH 
AC 2H 3H 8H AS KD QS QD KC 3S 6D 9S 6H 
JH ? 5C TC QC 8S JS 6C 2D KS TS AD 2C
$./shuffle
QH TC 5H AD 3C QS 4S TH 9S 8S 5D 6C JC 
KH JH AS KS JD 7S AC 7H 6H 6D 3S 2C 3D 
5C ? 7D JS 4C QC 9C 3H 8C 2D TS 2S QD 
5S KC 4H 8D 8H KD AH TD 9D 7C 6S 2H 9H

Edit: The issue was that trying to access the -1th element of an array causes C to access data outside of the array. Thank you!

This is my main code:

    /* Simulate a deck of cards (array of Card structures) and shuffle 
    the deck
         * Then the shuffled deck is printed to the terminal window. */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define DECK_SIZE (52) //52 cards in a deck

struct card { //define the structure of a card
  char suit[2]; //the suit on the card
  char value[2]; //the value of the card
};
typedef struct card Card; //define a Card type structure

Card deck[DECK_SIZE]; //a deck of cards is an array of 52 Card structures

#include "myheader.h" //myheader includes the shuffle() function for arrays of Cards

int main() {

  char suits[5] = "HCDS"; //the 4 suits
  char values[14] = "23456789TJQKA"; //the card values (T is 10)

  int j,k; //counting variables
  //fill the deck with the cards 
  for (j=0; j < 4; j++) {  //For each suit...
    for(k=0; k < 13; k++) { //and for each value...
      //Give the next card in the list that suit and value.
      deck[ ( j * 13 ) + ( k ) ].value[ 0 ] = values[ k ]; //assign the card's value
      deck[ ( j * 13 ) + ( k ) ].suit[ 0 ] = suits[ j ]; //assign the card's suit
    }
  }

  //Shuffle the deck (implementing Fisher-Yates Shuffle)
  int length = sizeof(deck)/sizeof(deck[0]);
  //shuffle function is found in "myheader.h"
  shuffle( &deck[0], length ); //pass a pointer to the first position of the deck

  //Print the deck to the screen (assuming 52 card deck)
  for (j=0; j < 4; j++) { //for each suit...
    for (k=0; k < 13; k++) { //for each value...
      //print the card
      printf("%s%s ", deck[ ( j * 13 ) + ( k ) ].value, deck[ ( j * 13 ) + ( k )].suit); 
    }
    //print a new line so the rows are organized into 4 rows of 13 cards each.
    printf("\n");
  }
}
//End of program.

And this is my header where I define the shuffle function:

//Requires math.h
//Requires stdlib.h
//Requires time.h

void shuffle(Card deck[], int length) { //takes an pointer to the array of type Card
  //This shuffle function implements the Fisher-Yates shuffle algorithm.
  printf("Length is: %i\n",length);
  int element;
  Card temp; //a place to temporarily store cards while shuffling them.
  srand(time(NULL)); //seed the random number generator with the current time.

  while (length) {
    //While there are things to shuffle
    //Pick a remaining element from the un-randomized elements
    element = rand() % (length); 
    length--; //decrease the "length" of the part of the array that is still unshuffled

    //Swap the element with the last element in the list.
    temp = deck[length]; //temporarily store the end object in the last slot
    deck[length] = deck[element-1];
    //place the selected element in the 'vacated' last slot
    deck[element-1] = temp;
    //put the temporarily stored object in place of the element 
  }
}
//There is a bug where one of the elements in the array gets changed to a ?

I suspect that one of the Structures that is stored in the temp structure in the shuffle function gets messed up when it gets passed edited, but I am not sure why only one object gets messed up in this was as, presumably, each element in the array gets placed into temp at one point during the shuffle loop. I am a beginner with C, I know enough to write things, but not enough about what is actually going on to begin to debug strange behavior like this. If anyone had any information about where this "?" character is coming from or why it is inserted in the array that would be very helpful. Thanks!

Upvotes: 0

Views: 66

Answers (1)

cleblanc
cleblanc

Reputation: 3688

element = rand() % (length);

gives you a value between 0 and length-1.

deck[length] = deck[element-1];

Can access outside your array when element is 0

Upvotes: 2

Related Questions