finite state machine for reading password - c

I'm trying to read the input from a user using keypad 4x4 and compare the input using a finite state machine as shown below.
When I come to case fourth my state machine does not go to Check case but to the default instead and then takes a key to go to CHECK immediately which makes the user press five times instead of 4.
while (1)
{
key=get_key();
if (key>=0 && key <=9){
switch (password){
case FIRST:
if (key==7 && i==0)
{
temp++; // increasing every time we enter correct number
password=SECOND;
HAL_Delay(300);
break;
}
HAL_Delay(300);
i++; // To check if we have fed in wrong digit
if(i==4) {
password=CHECK;
}
break;
//**********************************************************************************************************
case SECOND:
if (key==3 && temp==1){
temp++;
HAL_Delay(300);
password=THIRD;
break;
}
HAL_Delay(300);
i++;
if((i==3) || (i==2)) {
password=CHECK;
}
break;
//****************************************************************************************************
case THIRD:
if (key==9 && temp==2)
{
temp++;
HAL_Delay(300);
password = FOURTH;
break;
}
HAL_Delay(300);
i++;
if((i==2) || (i==1)) {
password=CHECK;
}
break;
//*******************************************************************************************************
case FOURTH:
if (key==2 && temp==3)
{
temp++;
password=CHECK;
break;
}
//HAL_Delay(300);
i++;
if(i==1) {
password=CHECK;
}
break;
//****************************************************************************************************
case CHECK:
if (temp==4){ // if temp has incresed to 4 that means that all the numbers entered are correct
HAL_GPIO_WritePin(Led_test_GPIO_Port,Led_test_Pin,1);
HAL_GPIO_WritePin(Led2_test_GPIO_Port,Led2_test_Pin,0);
password=IDLE_PASSWORD;
}
else if((i==4) || (i==3) || (i==2) || (i==1)) {
HAL_GPIO_WritePin(Led2_test_GPIO_Port,Led2_test_Pin,1);
HAL_GPIO_WritePin(Led_test_GPIO_Port,Led_test_Pin,0);
password=IDLE_PASSWORD;
}
break;
//******************************************************************************************************
case IDLE_PASSWORD:
temp=0;
i=0;
password = FIRST;
break;
default:
password = FIRST;
break;
}
}
}

while (1)
{
static uint8 Password[4] = {7, 3, 9, 2};
static uint8 Guesses = 0;
static uint8 Wrong = 0;
/*Get the key*/
key=get_key();
/*If the key is not in range...*/
if (key<0 || key >9)
{
/*Return early*/
return;
}
/*Wait 300*/
HAL_Delay(300);
/*If the value at the Guess position is not equal to what they pressed...*/
if (key != Password[Guesses])
{
/*Mark the input as wrong*/
Wrong = 1
}
/*Increment Guesses for the next time*/
Guesses++;
/*After their fourth input...*/
if (Guesses == 4)
{
/*Reet Guesses*/
Guesses = 0;
/*If they were wrong...*/
if (Wrong == 1)
{
/*Reset Wrong*/
Wrong = 0;
}
/*Otherwise if they were right...*/
else
{
/*Do something*/
}
}
}
This is untested - debug a bit and it should work.

Related

Why is my C program not counting correctly? Card game

I've created a card game that compares two cards of two players and determines a winner based on certain conditions. I have a function that compares the cards and returns true or false depending on the winner of the round. I call it inside a loop in my function that runs the game and the number of iterations is based on the number of cards dealt to each player. Theres something with my compare card function that allows for some rounds to fail comparison tests and I cannot tell why. The result is that my players win counts are off at the end of the game. Ive tried playing with the conditions at various points but I cannot find the issue.
Compare cards function - on seemingly random rounds the print condition at the end will execute telling me I've slipped through the other conditions
bool compareCards(char *card1, char *card2)
{
char card1Face = card1[0];
char card2Face = card2[0];
//if card1 is A/K/Q/J and card2 is num
if ((card1Face >= 'A' && card1Face <= 'Z') && !(card2Face >= 'A' && card2Face <= 'Z'))
{
return true;
}
//if card1 is num and card2 is A/K/Q/J
else if (!(card1Face >= 'A' && card1Face <= 'Z') && (card2Face >= 'A' && card2Face <= 'Z'))
{
return false;
}
//if card1 and card2 both A/K/Q/J
else if ((card1Face >= 'A' && card1Face <= 'Z') && (card2Face >= 'A' && card2Face <= 'Z'))
{
//test for A
if (card1Face == 'A' && card2Face != 'A')
{
return true;
}
else if (card1Face != 'A' && card2Face == 'A')
{
return false;
}
//test for K
if (card1Face == 'K' && card2Face != 'K')
{
return true;
}
else if (card1Face != 'K' && card2Face == 'K')
{
return false;
}
//test for Q
if (card1Face == 'Q' && card2Face != 'Q')
{
return true;
}
else if (card1Face != 'Q' && card2Face == 'Q')
{
return false;
}
//test for J
if (card1Face == 'J' && card2Face != 'J')
{
return true;
}
else if (card1Face != 'J' && card2Face == 'J')
{
return false;
}
} //end cards are face cards
//If card1 and card2 are nums
else if ((card1Face >= '1' && card1Face <= '9') && (card2Face >= '1' && card2Face <= '9'))
{
//if card1 is 10 and card2 is not
if (card1Face == '1' && card2Face != '1')
{
return true;
}
//if card2 is 10 and card1 is not
else if (card1Face != '1' && card2Face == '1')
{
return false;
}
//if card1 higher than card2
else if (card1Face > card2Face)
{
return true;
}
//if card1 lower than card2
else if (card1Face < card2Face)
{
return false;
}
} //end cards are nums
//if card1 and card2 same face value
else if (card1Face == card2Face)
{
char card1Suit = card1[strlen(card1) - 1];
char card2Suit = card2[strlen(card2) - 1];
//test for spade
if (card1Suit == 'S')
{
return true;
}
else if (card2Suit == 'S')
{
return false;
}
//test for Hearts
if (card1Suit == 'H')
{
return true;
}
else if (card2Suit == 'H')
{
return false;
}
//test for Diamonds
if (card1Suit == 'D')
{
return true;
}
else if (card2Suit == 'D')
{
return false;
}
//test for Clubs
if (card1Suit == 'C')
{
return true;
}
else if (card2Suit == 'C')
{
return false;
}
}
printf("IF THIS PRINTS UH OH");
return EXIT_SUCCESS;
}
The main playGame function
void playGame(void)
{
srand(time(NULL));
//initialize deck
char *(*deck)[13] = initializeDeck();
deck = shuffleDeck(deck);
bool quit = false;
while (1)
{
printHeaderDeal();
//user input loop
while (1)
{
fflush(stdin);
char choice = getchar();
//if enter to deal
if (choice == '\n')
{
break;
}
//if q to quit
else if (choice == 'q' || choice == 'Q')
{
printf("You chose to quit\n");
quit = true;
break;
}
//handling wrong input
else
{
printf("Incorrect choice! Please choose ENTER to deal or q to quit. \n");
scanf("%*[^\n]%*c");
}
} //end user input
//if quit selected break from loop
if (quit == true)
{
break;
}
int numCardsToDeal;
//user selects number of cards to deal
while (1)
{
printf("How many cards would you like to deal? 2-20\n");
scanf(" %d", &numCardsToDeal);
scanf("%*[^\n]");
//set range = even number between 2-20
if (numCardsToDeal >= 2 && numCardsToDeal <= 20)
{
if (numCardsToDeal % 2 == 1)
{
printf("Players must have same amount of cards in hand. Pick an even amount to deal.\n");
}
else
{
break;
}
}
else
{
printf("Incorrect selection.\n");
}
}//end num to deal selection and validation
//call deal cards and subtract the return value from the remaining card total
cardsRemaining -= dealCards(deck, numCardsToDeal);
bool result;
Here is where I print the players hands, call the compare function and count the wins based on each round
int length1 = sizeof(player1Hand)/sizeof(player1Hand[0]);
printf("\n\n");
printf("Player 1 hand: ");
for(int i = 0; i < length1; i++)
{
printf("[%s]", player1Hand[i]);
}
printf("\n\n");
int length2 = sizeof(player2Hand)/sizeof(player2Hand[0]);
printf("Player 2 hand: ");
for(int i = 0; i < length2; i++)
{
printf("[%s]", player2Hand[i]);
}
printf("\n\n");
//loop through player hands based on num of dealt cards, call compareCards on each iteration and store results of each comparison
for (int i = 0; i < (numCardsToDeal / 2); i++)
{
result = compareCards(player1Hand[i], player2Hand[i]);
if (result == true)
{
player1Wins++;
}
else if (result == false)
{
player2Wins++;
}
}
//if run out of cards end game
if (cardsRemaining == 0)
{
printf("No more cards remaining in deck. Game over.\n\n");
break;
}
} //end game
printf("Total wins for player 1: %d\n", player1Wins);
printf("Total wins for player 2: %d\n", player2Wins);
free(deck);
}
I'm not sure if this will actually solve the issue, but this is too long for a comment:
There may be some other logic issues, but the first thing I've noticed is in your test for cards with numbers:
//If card1 and card2 are nums
else if ((card1Face >= '1' && card1Face <= '9') && (card2Face >= '1' && card2Face <= '9'))
{
// snipped
} //end cards are nums
If card1Face and card2Face are both the same number, no condition will match, so it will fall through.
Note, that even though you have another else if test for if the cards are equal, that's below this case and will NOT be run, because you've already matched one else if condition.
So, this may not fix the issue completely, but I think if you move the check for card1Face == card2Face up to be one of the earlier checks, then you can at least remove a few cases where it will not work as you're expecting. Actually, I think you should make the equal card check the first check; make the if condition card1Face == card2Face, then all of the others to be else if.
Finally, for the sake of debugging, if it's still not working properly after that change, add an else block that just prints the two card values; you may start to see a pattern which will help find where other problems might be occurring.

Check if input string is parenthesis completed

I'm trying to write a function, that would check for a matching parentheses.
For example, if the given string is "(1+1))" it would print false otherwise it's true.
However, in my code it's printing false no matter what the case is.
bool isMatched(char pran[]) {
bool completetd = true;
int count = 0;
for (int i = 0; pran[i] != '\0'; i++) {
if (pran[i] == '('){
count++;
}
else {
// It is a closing parenthesis
count--;
}
if (count < 0) {
// there are more Closing parenthesis
completetd = false;
break;
}
// If count is not zero, there are more opening parenthesis
if (count != 0) {
completetd = false;
}
}
return completetd;
}
int main() {
char arr[] = "((1+a))";
if (isMatched(arr)) {
printf("TRUE \n");
}
else {
printf("FALSE \n");
}
return 0;
}
I would appreciate any help.
You can try this not sure if this is what you are looking for.
bool isMatched(char pran[]) {
int open = 0;
int close = 0;
for (int i = 0; pran[i] != '\0'; i++) {
if (pran[i] == '('){
open++;
}
if (pran[i] == ')'){
close++;
}
}
// Check if both match
if(open == close){
return true;
}
return false;
}
int main() {
char arr[] = "((1+a))";
if (isMatched(arr)) {
printf("TRUE \n");
}
else {
printf("FALSE \n");
}
return 0;
}
By adding a
printf("got 1 (!\n"); next to count++;
and a
printf("got 1 )!\n"); next to count--;,
you get:
Got 1 (!
Got 1 (!
Got 1 )!
Got 1 )!
Got 1 )!
FALSE
This shows that you have a validation problem with your checking logic
As pointed-out in the comments, replace your else with else if (pran[i] == ')') { will fix that part for you.
But the real problem lies with your last validation.
Take it out of the for loop. It sets the value to false as soon as you detect a parenthesis.
Thus, take this:
// If count is not zero, there are more opening parenthesis
if (count != 0) {
printf("Count: %d\n",count);
completetd = false;
}
}
and make it this:
}
// If count is not zero, there are more opening parenthesis
if (count != 0) {
printf("Count: %d\n",count);
completetd = false;
}

Line in text file is evaluated multiple times?

I need to convert infix to postfix and evaluate postfix expression. When reading from a file, I should be able to evaluate multiple expressions at once. But when I run it and it encounters an expression that is not well-formed in the sense that there are more closed parentheses than open ones, it evaluates that expression 2 or 3 times.
Code:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1000
typedef struct stack
{
int data[MAX];
int top;
} stack;
int priority(char);
void init(stack*);
int empty(stack*);
int full(stack*);
char pop(stack*);
void push(stack*, char);
char top(stack*);
void add(char*, char, int);
void keyboard();
void read_file();
int change(char);
void pushYO(double);
double popYO();
stack s;
char x;
int i, token, topYO = -1;
double result[MAX];
char filepath[MAX];
int main()
{
char choice;
init(&s);
system("CLS");
printf("[1] Keyboard \n[2] Read from text file \n[3] Exit \n");
scanf("%c", &choice);
if(choice != '1' && choice != '2' && choice != '3')
{
main();
}
else if(choice == '1')
{
keyboard();
}
else if(choice == '2')
{
read_file();
}
else if(choice == '3')
{
printf("\nThank you for using Kei Shirabe's \ninfix to postfix converter and evaluator! :)\n");
exit(0);
}
}
void keyboard() //the keyboard input version. this works fine
{
//code here
}
void read_file()
{
int z, count, form, paren;
double one, two, three = 1;
char infx[MAX];
char pofx[MAX];
char choice;
FILE *text = fopen("text.txt", "a");
printf("Enter path of file:");
scanf("%s",&filepath);
FILE *textYO = fopen(filepath, "r");
if((textYO) == NULL)
{
printf("\nError! Unable to open %s\n\n", filepath);
}
else
{
while((fgets(infx, MAX, textYO))!= NULL)
{
form = -1, paren = 0, count = 0, z = 0;
infx[
strlen(infx)-1] = '\0';
for (i=0; i<strlen(infx); i++)
{
if((token = infx[i]) != '\n')
{
if(isalnum(token))
{
form++;
}
else
{
if(token == '(')
{
paren++;
}
else if(token == ')')
{
paren--;
}
else
{
form--;
}
}
if (paren < 0)
{
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nError! Not well formed :( \n-----------------\n");
fprintf(text, "\n\nError! Not well formed :( \n-----------------\n");
}
else
if(isalnum(token))
{
add(pofx, token, count);
count++;
}
else
if(token == '(')
{
push(&s, '(');
}
else
{
if(token == ')')
while((x = pop(&s)) != '(')
{
add(pofx, x, count);
count++;
}
else
if(token == '^')
{
push(&s, token);
}
else
{
while(priority(token) <= priority(top(&s)) && !empty(&s))
{
x = pop(&s);
add(pofx, x, count);
count++;
}
push(&s, token);
}
}
}
else
{
while(!empty(&s))
{
x = pop(&s);
add(pofx, x, count);
count++;
}
}
}
if(form != 0 || paren != 0)
{
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nError! Not well formed :( \n-----------------\n");
fprintf(text, "\n\nError! Not well formed :( \n-----------------\n");
}
else
{
form = -1, paren = 0;
printf("%s", infx);
fprintf(text, "%s", infx);
printf("\n\nPostfix: %s \n\n", pofx);
fprintf(text, "\n\nPostfix: %s\n\n", pofx);
while((token = pofx[z++]) != '\0')
{
three = 1;
if(!isdigit(token) && !isalpha(token))
{
two = popYO();
one = popYO();
switch(token)
{
case '+':
pushYO(one+two); break;
case '-':
pushYO(one-two); break;
case '*':
pushYO(one*two); break;
case '/':
pushYO(one/two); break;
case '^':
if (two > 0)
{
for(i=0;i<two;i++)
{
three = three * one;
}
pushYO(three);
three = 1; break;
}
else
{
for(i=0;i<(two-(2*two));i++)
{
three = three * one;
}
pushYO((1/three));
three = 1; break;
}
}
}
else if(isalpha(token))
{
if(isupper(token))
{
pushYO(token - '#');
}
if(islower(token))
{
pushYO(token - change(token));
}
}
else
{
pushYO(token - '0');
}
}
printf("Result: %lf\n-----------------\n", result[topYO]);
fprintf(text, "Result: %lf\n-----------------\n", result[topYO]);
}
}
}
fclose(text);
fclose(textYO);
printf("\nRun again? \n[1] Yes \n[any other key] No\n");
scanf("%c", &choice);
scanf("%c", &choice);
if(choice == '1')
{
main();
}
else
{
printf("\nThank you for using Kei Shirabe's \ninfix to postfix converter and evaluator! :)\n");
exit(0);
}
}
//other functions down here, not important
Sample text file (and yes there is an extra space at the end):
(1+2))
(1+2*3)
For this text file, the expression (1+2)) is evaluated three times, each result being "Not well formed". The last expression works as expected.
Any help please?

C SDL Keyboard Events SDL_KEYUP Triggering When Key Is Down

I am using SDL in C, and I'm trying to make a character move on the screen when a key is pressed, and stop when it is released, but it seems as if the KEYUP event is triggering when the key is still being held down. If I remove the KEYUP section in pressed(), the characters will slide across the screen, but obviously won't stop on their own. If I leave the KEYUP section in, I have to press the key repeatedly to move them across the screen.
Any idea what I'm doing wrong?
Here's what I have:
...
int done = 0;
while (done==0)
{
pressed();
if (kenter == 1)
{
state = 1;
subscreen();
}
if (kescape == 1)
{
done = 1;
}
if (kup == 1)
{
playery += -2;
}
if (kdown == 1)
{
playery += 2;
}
if (kright == 1)
{
playerx += 2;
}
if (kleft == 1)
{
playerx += - 2;
}
...
int pressed ()
{
SDL_Event keyevent;
while (SDL_PollEvent(&keyevent))
{
switch(keyevent.type)
{
case SDL_KEYDOWN:
switch(keyevent.key.keysym.sym)
{
case SDLK_RETURN:
{
kenter = 1;
break;
}
case SDLK_ESCAPE:
{
kescape = 1;
break;
}
case SDLK_a:
{
ka = 1;
break;
}
case SDLK_s:
{
ks = 1;
break;
}
case SDLK_UP:
{
kup = 1;
break;
}
case SDLK_DOWN:
{
kdown = 1;
break;
}
case SDLK_RIGHT:
{
kright = 1;
break;
}
case SDLK_LEFT:
{
kleft = 1;
break;
}
default:
break;
}
}
switch(keyevent.type)
{
case SDL_KEYUP:
switch(keyevent.key.keysym.sym)
{
case SDLK_RETURN:
{
kenter = 0;
break;
}
case SDLK_ESCAPE:
{
kescape = 0;
break;
}
case SDLK_a:
{
ka = 0;
break;
}
case SDLK_s:
{
ks = 0;
break;
}
case SDLK_UP:
{
kup = 0;
break;
}
case SDLK_DOWN:
{
kdown = 0;
break;
}
case SDLK_RIGHT:
{
kright = 0;
break;
}
case SDLK_LEFT:
{
kleft = 0;
break;
}
default:
break;
}
}
}
return 0;
}
I think your switch statements are broken.
Use this less confusing way
int pressed ()
{
SDL_Event event;
while(SDL_PollEvent(&event) )
{
if(event.type == SDLK_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
doStuff = 1
break;
default:
break;
}
}
if(event.type == SDLK_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_RETURN:
doStuff = 0;
break;
default:
break;
}
}
}
}
Also important:
SDL Tutorials: Practical Keyboard Input
Oh and avoid using global variables!
Your use of two switch statements is odd and confusing, you should probably fix that.
The issues you're seeing are likely due to keyboard repeat, see the SDL_EnableKeyRepeat() call for how to disable it.
don't use switch. I experienced same thing, but I resolved into using 'if' like this. Maybe switch has 'else if'.
if(event.type == SDL_KEYDOWN){
....
}
if(event.type == SDL_KEYUP){
....
}

Pointer assignment using malloc going wrong [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Please feel free to copy paste and try it out, it stops working halfway through function handget when individual hand is assigned a space in memory
/*
* A program that is meant to classify five-card poker hands.
*Is still in progress
*/
#include<stdio.h>
#include<math.h>
#include<ctype.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#define SEED 7
#define SIZE 5
/*
*
*/
typedef enum suits {
clubs,
diamonds,
hearts,
spades
} suits;
typedef enum values {
zero,
one, // not used, but ensures numerical values correspond
two,
three,
four,
five,
six,
seven,
eight,
nine,
ten,
jack,
queen,
king,
ace
} values;
typedef struct cards {
suits suit;
values value;
} cards;
int islegal(cards *hand, int nr_of_cards);
/* Given any number of cards, determines whether any duplicates
* or false cards are present or not. If so, returns 0, otherwise 1.
*/
int flop(cards **handPtr);
/* Asks the user to input a hand of cards;
* returns the number of cards being input
*/
int *rawtoflop (cards *handPtr, int nr_of_cards);
int hander(cards **handPtr,int counter);
int handget(cards **playerhands,cards *thishands, int handsize);
void printsuit(suits thissuit);
/* Prints the enum-type suits
*/
void printvalue(values thisvalue);
/* Prints the enum-type values
*/
void printhand(cards *hand, int nr_of_cards);
/* Prints a hand of cards without further processing
*/
int main(void) {
cards *thishand, *playerhands;
flop(&thishand);
printhand(thishand,6);
handget(&playerhands,thishand,6);
return 0;
}
int islegal(cards *hand, int nr_of_cards) {
int i, fulldeck[4][13]={0};
int current_value, current_suit;
cards *current_card = hand;
int legal = 1;
for (i=0; i<nr_of_cards; i++) {
current_value = (int) (*current_card).value;
current_suit = (*current_card).suit;
// if the current card has value zero, it is not a valid hand
if (current_value==0) {
legal = 0;
break;
}
//check if the current card already appears, if yes invalid hand, if no,
//change the flag for that card in the full deck.
//Since (two) will correspond to fulldeck[.][0] there is a -2 offset.
if ( (fulldeck[current_suit][current_value - 2]) > 0 ) {
legal = 0;
break;
} else {
fulldeck[current_suit][current_value - 2]++;
}
current_card++;
}
return legal;
}
int flop(cards **handPtr) {
int i,*q=NULL,n=NULL;
int j[5]={0,0,0,0,0};
int k[5]={1,1,1,1,1},nr_of_cards = 5;//for more/less cards CHANGE HERE!
char rawsuit, rawcard[4];
// allocate the required amount of memory for your cards
(*handPtr) = (cards *) malloc(nr_of_cards * sizeof(cards));
n=memcmp(j,k,sizeof(j));
while(n!=0) {
printf("Please input the five cards on the table: ");
q=rawtoflop(*handPtr,nr_of_cards);
for (i=0;i<nr_of_cards;i++) {
j[i]=*(q+i);
}
n=memcmp(j,k,sizeof(j));
}
free(&handPtr);
return nr_of_cards;
}
int *rawtoflop (cards *handPtr, int nr_of_cards){
int i,m[5],*mPtr;
char rawsuit, rawcard[4];
mPtr=m;
// ask for the cards
for (i=0; i<nr_of_cards; i++)/* do */{
scanf("%3s", &rawcard);
rawsuit = rawcard[0];
if (rawcard[1]=='1') {
if (rawcard[2]=='0') {
(handPtr)[i].value = ten;
} else {
(handPtr)[i].value = zero;
}
} else if (rawcard[1]=='2') {
(handPtr)[i].value = two;
} else if (rawcard[1]=='3') {
(handPtr)[i].value = three;
} else if (rawcard[1]=='4') {
(handPtr)[i].value = four;
} else if (rawcard[1]=='5') {
(handPtr)[i].value = five;
} else if (rawcard[1]=='6') {
(handPtr)[i].value = six;
} else if (rawcard[1]=='7') {
(handPtr)[i].value = seven;
} else if (rawcard[1]=='8') {
(handPtr)[i].value = eight;
} else if (rawcard[1]=='9') {
(handPtr)[i].value = nine;
} else if (rawcard[1]=='J') {
(handPtr)[i].value = jack;
} else if (rawcard[1]=='Q') {
(handPtr)[i].value = queen;
} else if (rawcard[1]=='K') {
(handPtr)[i].value = king;
} else if (rawcard[1]=='A') {
(handPtr)[i].value = ace;
} else {
(handPtr)[i].value = zero;
}
switch (rawsuit) {
case 'h':
(handPtr)[i].suit = hearts;
break;
case 'd':
(handPtr)[i].suit = diamonds;
break;
case 'c':
(handPtr)[i].suit = clubs;
break;
case 's':
(handPtr)[i].suit = spades;
break;
default:
(handPtr)[i].value = zero;
}
m[i]=(islegal(handPtr,i+1));
}
return mPtr;
}
int hander(cards **handPtr,int counter) {
int i, nr_of_cards = 2;
char rawsuit, rawcard[4];
if(counter==0){
// allocate the required amount of memory for your cards
(*handPtr) = (cards *) malloc(nr_of_cards * sizeof(cards));
}
// ask for the cards
for (i=0; i<nr_of_cards; i++) do {
scanf("%3s", &rawcard);
rawsuit = rawcard[0];
if (rawcard[1]=='1') {
if (rawcard[2]=='0') {
(*handPtr)[i].value = ten;
} else {
(*handPtr)[i].value = zero;
}
} else if (rawcard[1]=='2') {
(*handPtr)[i].value = two;
} else if (rawcard[1]=='3') {
(*handPtr)[i].value = three;
} else if (rawcard[1]=='4') {
(*handPtr)[i].value = four;
} else if (rawcard[1]=='5') {
(*handPtr)[i].value = five;
} else if (rawcard[1]=='6') {
(*handPtr)[i].value = six;
} else if (rawcard[1]=='7') {
(*handPtr)[i].value = seven;
} else if (rawcard[1]=='8') {
(*handPtr)[i].value = eight;
} else if (rawcard[1]=='9') {
(*handPtr)[i].value = nine;
} else if (rawcard[1]=='J') {
(*handPtr)[i].value = jack;
} else if (rawcard[1]=='Q') {
(*handPtr)[i].value = queen;
} else if (rawcard[1]=='K') {
(*handPtr)[i].value = king;
} else if (rawcard[1]=='A') {
(*handPtr)[i].value = ace;
} else {
(*handPtr)[i].value = zero;
}
switch (rawsuit) {
case 'h':
(*handPtr)[i].suit = hearts;
break;
case 'd':
(*handPtr)[i].suit = diamonds;
break;
case 'c':
(*handPtr)[i].suit = clubs;
break;
case 's':
(*handPtr)[i].suit = spades;
break;
default:
(*handPtr)[i].value = zero;
}
} while (!islegal(*handPtr, i+1));
return nr_of_cards;
}
int handget(cards **playerhand,cards *thishands, int handsize) {
cards *player=NULL,*individualhand=NULL;
int nr_players=1;
(*playerhand) = (cards *) malloc(7*sizeof(cards));
memcpy(*playerhand,thishands,handsize*sizeof(cards));
printf("Please enter the cards for player 1: ");
hander(&player,0);
memcpy(*playerhand+5,player,7*sizeof(cards));
printf("1 we made it this far chaps!!!\n");
individualhand =(cards *) malloc(7*sizeof(cards));//THIS IS WHERE IT ALL GOES WRONG!!
printf("2 we made it this far chaps!!\n");
return nr_players;
}
void printsuit(suits thissuit) {
switch (thissuit) {
case diamonds:
printf("d");
break;
case clubs:
printf("c");
break;
case hearts:
printf("h");
break;
case spades:
printf("s");
break;
}
return;
}
void printvalue(values thisvalue) {
switch (thisvalue) {
case two:
printf("2");
break;
case three:
printf("3");
break;
case four:
printf("4");
break;
case five:
printf("5");
break;
case six:
printf("6");
break;
case seven:
printf("7");
break;
case eight:
printf("8");
break;
case nine:
printf("9");
break;
case ten:
printf("10");
break;
case jack:
printf("J");
break;
case queen:
printf("Q");
break;
case king:
printf("K");
break;
case ace:
printf("A");
break;
}
return;
}
void printhand(cards *hand, int nr_of_cards) {
int i;
for (i=0; i<nr_of_cards; i++) {
printsuit((hand[i]).suit);
printvalue((hand[i]).value);
printf(" ");
}
printf("\n");
return;
}
You allocate enough space for 7 cards:
(*playerhand) = (cards *) malloc(7*sizeof(cards));
Then you copy seven cards into *playerhand+5:
memcpy(*playerhand+5,player,7*sizeof(cards));
So you get a buffer overflow. *playerhand+5 is the same as &(*playerhand)[5]. So you're copying 7 cards into the fifth place in an array with enough capacity for 7 cards.
That's one problem of using magic number. I can't guess what this "5" means if you don't give it a name (nor why 7 cards).
Actually the problem is not that you're copying TO thishands but that you are copying FROM thishands. You allocated 5*sizeof(cards) to thishands,but when calling handget, you're calling it with handget(&playerhands,thishand,6);. The last argument is 6, and therein lies your problem.
Get rid of all these magic numbers. Instead make them (and this is strictly because you seem to be using C not C++) #defines. That way you have a consistent number to work with.

Resources