c - 我的代码中没有出现错误,但是当我的程序到达“chooseCard”函数时,它会终止
问题描述
我需要让玩家从他们手中的 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;
}
输出应该用卡片组中的卡片替换所选卡片。
解决方案
当我编译你的代码时,我得到:
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
想要 a但在声明为包含from的变量中card*
传递了a并继续将西装字符串的中间解释为下一个指针并崩溃访问未分配的内存。card**
card*
chooseCards()
推荐阅读
- c - 使用命令行参数的结构链表
- go - 在 golang 中捕获 stdErr 输出
- c# - 在 asp.net 中插入 asp 按钮使用 C# 代码隐藏页面中的 HTML
- numpy - 是否可以沿轴为 ndarray 执行 linalg.multi_dot ?
- php - PHP 类属性:传递 id 还是完整对象?
- django - 让 Django 序列化程序返回两个平面列表
- python - 如何访问/操作 keras 模型中的张量元素?
- java - 如何使用继承的实体对 REST API 建模?
- tomcat - Babel 资产管道的 Grails 部署问题
- python - 如何在石墨烯 mongo python 中更新 EmbeddedDocument 的字段