我的代码中没有出现错误,但当我的程序到达“chooseCard”函数时,它会终止

问题描述 投票:-1回答:1

我需要让玩家从他们的5张牌中选择他们想要保留的牌。我试图在我的chooseCards函数中执行此操作,但是当用户选择更换卡时,它会终止并且没有错误。

我试过改变函数中的指针类型,希望这是问题,但没有改变。当用户输入“n”(替换卡)时,程序退出。但是,passCard函数在程序的早期工作和shuffle函数一起完美无缺,所以我对问题所在的地方感到困惑。我知道使用数组会更容易,但是赋值需要链接列表。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>


typedef struct card_s {
    char suit[20];
    int face;
    struct card_s *next;
}card;


void makeDeck(card** currentCard) {
    int i, j;
    char cardsuit[20];
    card *tempCard = '-', *tail = NULL, *lastcard = NULL;

    for (i = 0; i < 13; i += 1) {   // 13 cards per suit

        for (j = 0; j < 4; j += 1) {    // 4 suits
            tempCard = (card*)malloc(sizeof(card));
            if (j == 0) {
                strcpy(cardsuit, "of diamonds");
            }
            else if (j == 1) {
                strcpy(cardsuit, "of hearts");
            }
            else if (j == 2) {
                strcpy(cardsuit, "of clubs");
            }
            else if (j == 3) {
                strcpy(cardsuit, "of spades");
            }

            tempCard->face = i + 1;

            strcpy(tempCard->suit, cardsuit);


            tempCard->next = NULL;

            lastcard = tempCard;

            if (*currentCard == NULL) {

                *currentCard = tempCard;

            }

            else {

                tail->next = tempCard;

            }

            tail = tempCard;

            tail->next = NULL;  //sets final card place in list to null

        }
    }

    return;
}

int FindLength(card* currentcard) {
    int i = 0;
    while (currentcard != NULL) {
        i += 1; //increment i evry time current card has value
        currentcard = currentcard->next;
    }
    return i;
}

void shuffleDeck(card** currentCard, int deckLength) {

    int cardcount, place, i, rng;
    int j = 0;

    card *shuffled = NULL;
    card *unshuffled = NULL;
    card *tempCard = NULL;


    srand(time(NULL));


    for (place = 0; place < deckLength; place += 1) {

        shuffled = *currentCard;
        unshuffled = *currentCard;


        tempCard = (card*)malloc(sizeof(card));

        rng = rand() % deckLength;

        for (cardcount = 0; cardcount < rng; cardcount += 1) {
            unshuffled = unshuffled->next;
        }
        for (cardcount = 0; cardcount < place; cardcount += 1) {
            shuffled = shuffled->next;
        }

        strcpy(tempCard->suit, unshuffled->suit);   //swap the suits of each card
        strcpy(unshuffled->suit, shuffled->suit);
        strcpy(shuffled->suit, tempCard->suit);

        tempCard->face = unshuffled->face;      //swap value of the cards
        unshuffled->face = shuffled->face;
        shuffled->face = tempCard->face;

    }

    return;
}

void pushFront(card** head, char* suit, int face) {

    card* temp = (card*)malloc(sizeof(card));

    temp->face = face;
    strcpy(temp->suit, suit);
    temp->next = *head;

    *head = temp;   //new card put at head of list
}

void removeFront(card **head) {

    card* temp = NULL;

    temp = *head;       //point temp to first card

    *head = (*head)->next;      //set head to the next card

    free(temp);     //free the first 

}

void passCard(card** giver, card** taker) {

    pushFront(taker, (*giver)->suit, (*giver)->face);
    removeFront(giver);

    return;
}

void dealCards(card** deck, card** p1, card** p2) {

    card* current = NULL;

    current = *deck;

    for (int i = 0; i < 10; i++) {

        if (i % 2 == 0) {
            passCard(deck, p1);
        }
        else {
            passCard(deck, p2);
        }

    }
    return;
}

void chooseCards(card*hand, card*deck) {

    int i, chosenCard = 0;
    char answer;

    for (i = 1; i < 6; i += 1) {


        printf("Keep card %d? (y or n): ", i);
        scanf(" %c", &answer);

        if (answer == 'n') {
            passCard(hand, deck);
            shuffleDeck(deck, FindLength(deck));
            passCard(deck, hand);
        }
        hand = hand->next;

    }

    return;
}

int main() {
    card *cards = NULL;         //deck of cards
    card *player1 = NULL;       //p1 hand
    card *dealer = NULL;        //dealer hand

    makeDeck(&cards);   //create deck of 52 cards

    int deckLength = Findlength(cards);
    shuffleDeck(&cards, deckLength);    //shuffle deck of cards

    dealCards(&cards, &player1, &dealer);   //deal to player 1 and dealer

    //print player 1 hand

    chooseCards(&player1, &cards);

    //print player 1 hand, chosen cards have been replaced by cards in the deck

    return 0;
}

输出应该用卡片中的卡替换所选卡。

c linked-list
1个回答
0
投票

当我编译你的代码时,我得到:

joshua@nova:/tmpϟ gcc testshuffle.c
testshuffle.c: In function ‘makeDeck’:
testshuffle.c:18:22: warning: initialization of ‘card *’ {aka ‘struct card_s *’} from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
     card *tempCard = '-', *tail = NULL, *lastcard = NULL;
                      ^~~
testshuffle.c: In function ‘chooseCards’:
testshuffle.c:182:22: warning: passing argument 1 of ‘passCard’ from incompatible pointer type [-Wincompatible-pointer-types]
             passCard(hand, deck);
                      ^~~~
testshuffle.c:143:22: note: expected ‘card **’ {aka ‘struct card_s **’} but argument is of type ‘card *’ {aka ‘struct card_s *’}
 void passCard(card** giver, card** taker) {
               ~~~~~~~^~~~~
testshuffle.c:182:28: warning: passing argument 2 of ‘passCard’ from incompatible pointer type [-Wincompatible-pointer-types]
             passCard(hand, deck);
                            ^~~~
testshuffle.c:143:36: note: expected ‘card **’ {aka ‘struct card_s **’} but argument is of type ‘card *’ {aka ‘struct card_s *’}
 void passCard(card** giver, card** taker) {
                         ~~~~~~~^~~~~
testshuffle.c:183:25: warning: passing argument 1 of ‘shuffleDeck’ from incompatible pointer type [-Wincompatible-pointer-types]
             shuffleDeck(deck, FindLength(deck));
                         ^~~~
testshuffle.c:77:25: note: expected ‘card **’ {aka ‘struct card_s **’} but argument is of type ‘card *’ {aka ‘struct card_s *’}
 void shuffleDeck(card** currentCard, int deckLength) {
                  ~~~~~~~^~~~~~~~~~~
testshuffle.c:184:22: warning: passing argument 1 of ‘passCard’ from incompatible pointer type [-Wincompatible-pointer-types]
         passCard(deck, hand);
                  ^~~~
testshuffle.c:143:22: note: expected ‘card **’ {aka ‘struct card_s **’} but argument is of type ‘card *’ {aka ‘struct card_s *’}
 void passCard(card** giver, card** taker) {
               ~~~~~~~^~~~~
testshuffle.c:184:28: warning: passing argument 2 of ‘passCard’ from incompatible pointer type [-Wincompatible-pointer-types]
             passCard(deck, hand);
                            ^~~~
testshuffle.c:143:36: note: expected ‘card **’ {aka ‘struct card_s **’} but argument is of type ‘card *’ {aka ‘struct card_s *’}
 void passCard(card** giver, card** taker) {
                         ~~~~~~~^~~~~
testshuffle.c: In function ‘main’:
testshuffle.c:207:17: warning: passing argument 1 of ‘chooseCards’ from incompatible pointer type [-Wincompatible-pointer-types]
     chooseCards(&player1, &cards);
                 ^~~~~~~~
testshuffle.c:170:23: note: expected ‘card *’ {aka ‘struct card_s *’} but argument is of type ‘card **’ {aka ‘struct card_s **’}
 void chooseCards(card*hand, card*deck) {
                  ~~~~~^~~~
testshuffle.c:207:27: warning: passing argument 2 of ‘chooseCards’ from incompatible pointer type [-Wincompatible-pointer-types]
     chooseCards(&player1, &cards);
                           ^~~~~~
testshuffle.c:170:34: note: expected ‘card *’ {aka ‘struct card_s *’} but argument is of type ‘card **’ {aka ‘struct card_s **’}
 void chooseCards(card*hand, card*deck) {
                             ~~~~~^~~~

当我运行它时,我得到:

Program received signal SIGSEGV, Segmentation fault.
0x000055555555530d in FindLength ()
(gdb) bt
#0  0x000055555555530d in FindLength ()
#1  0x0000555555555618 in chooseCards ()
#2  0x00005555555556ce in main ()
(gdb) 

修复所有警告。你会发现你的问题。你在card*card**之间进行了糟糕的类型转换,导致FindLength崩溃。特别是,FindLength想要一个card*但是在card**声明包含card*的变量中传递了chooseCards()并继续将套装字符串的中间解释为下一个指针并且崩溃访问未分配的内存。

© www.soinside.com 2019 - 2024. All rights reserved.