Reputation: 175
The code is from Absolute beginner's guide to C, and I get this error ./BlackJack.c<41> : warning C4047: '==' : 'int' differes in levels of indirection from 'char [2]'
when I try to compile it in Visual Studio. This is the main function of a Blackjack game.
Line <41> is if (ans == "H") {
main()
{
int numCards; /* Equals 52 at the beginneing */
int cards[52], playerPoints[2], dealerPoints[2], total[2];
/* For user Hit/Stand or Yes/No response */
do { initCardsScreen(cards, playerPoints, dealerPoints, total, &numCards);
dealerGetsCard(&numCards, cards, dealerPoints);
printf("\n");
playerGetsCard(&numCards, cards, playerPoints);
playerGetsCard(&numCards, cards, playerPoints);
do {
ans = getAns("Hit or stand (H/S)? ");
if (ans == "H") {
platerGetsCard(&numCards, cards, playerPoints);
}
}
while ( ans != 'S');
totalIt(playerPoints, total, PLAYER);
/* Player's total */
do {
dealerGetsCard(&numCards, cards, dealerPoints);
} while (dealerPoints[ACEHIGH] < 17);
/* 17: Dealer stop */
totalIt(dealerPoints, total, DEALER);
/* Dealer's total */
findWinner(total);
ans = getAns("\nPlay again (Y/N)? ");
} while (ans == 'Y');
return;
}
(Update): Here is the entire code.
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <stdlib.h>
#define BELL '\a'
#define DEALER 0
#define PLAYER 1
#define ACELOW 0
#define ACEHIGH 1
int askedForName = 0;
/****************************
This program specific prototype
****************************/
void dispTitle(void);
void initCardsScreen(int cards[52], int playerPoints[2], int dealerPoints[2], int total[2], int * numCards);
int dealCard(int * numCards, int cards[52]);
void dispCard(int cardDrawn, int points[2]);
void totalIt(int points[2], int total[2], int who);
void dealerGetsCard(int *numCards, int cards[52], int dealerPoints[2]);
void playerGetsCard(int *numCards, int cards[52], int playerPoints[2]);
char getAns(char mesg[]);
char ans;
void findWinner(int total[2]);
main()
{
int numCards; /* Equals 52 at the beginneing */
int cards[52], playerPoints[2], dealerPoints[2], total[2]; /* For user Hit/Stand or Yes/No response */
do { initCardsScreen(cards, playerPoints, dealerPoints, total, &numCards);
dealerGetsCard(&numCards, cards, dealerPoints);
printf("\n");
playerGetsCard(&numCards, cards, playerPoints);
playerGetsCard(&numCards, cards, playerPoints);
do {
char ans = getAns("Hit or stand (H/S)? ");
if (ans == "H") {
playerGetsCard(&numCards, cards, playerPoints);
}
}
while ( ans != 'S');
totalIt(playerPoints, total, PLAYER);
/* Player's total */
do {
dealerGetsCard(&numCards, cards, dealerPoints);
} while (dealerPoints[ACEHIGH] < 17);
/* 17: Dealer stop */
totalIt(dealerPoints, total, DEALER);
/* Dealer's total */
findWinner(total);
ans = getAns("\nPlay again (Y/N)? ");
} while (ans == 'Y');
return;
}
void initCardsScreen(int cards[52], int playerPoints[2], int dealerPoints[2], int total[2], int *numCards)
{
int sub, val=1; /* This function's Work variables */
char firstName[15]; /* Holds user's first name */
*numCards = 52; /* Holds running total of number of cards */
for (sub = 0; sub <= 51; sub++) { /* Counts from 0 to 51 */
val = (val == 14) ? 1 : val; /* If val is 14 reset to 1 */
cards[sub] = val;
val++; }
for (sub = 0; sub <= 1; sub++) { /* Counts from 0 to 1 */
playerPoints[sub] = dealerPoints[sub] = total[sub]=0; }
dispTitle();
if (askedForName ==0) { /* Name asked for nly once */
printf("\nWhat is your first name? ");
scanf_s(" %s", firstName);
askedForName = 1; /* Don't ask prompt again */
printf("Ok, %s, get ready for casino action!\n\n", firstName);
getchar(); /* Discards newline. You can safely */
} /* ignore compiler warning here. */
return;
}
/*** This function gets a card for the player and updates the player's points. ***/
void playerGetsCard(int *numCards, int cards[52], int playerPoints[2])
{
int newCard;
newCard = dealCard(numCards, cards);
printf("You draw: ");
dispCard(newCard, playerPoints);
}
/*** This function gets a card for the dealer and updates the dealer's poimts. ***/
void dealerGetsCard(int *numCards, int cards[52], int dealerPoints[2])
{
int newCard;
newCard = dealCard(numCards, cards);
printf("The dealer draws: ");
dispCard(newCard, dealerPoints);
}
/*** This function gets a card from the deck and stores it in either the dealer's or the player's hold of cards ***/
int dealCard(int * numCards, int cards[52])
{
int cardDrawn, subDraw;
time_t t; /* Gets time for a random value */
srand((unsigned int)(time(&t))); /* Seeds random-number generator */
subDraw = (rand() % (*numCards)); /* From 0 to numcards */
cardDrawn = cards[subDraw];
cards[subDraw] = cards[*numCards -1]; /* Puts top card */
(*numCards); /* in place of drawn one */
return cardDrawn;
}
/*** Displays the last drawn card and updates points with it. ***/
void dispCard(int cardDrawn, int points[2])
{
switch (cardDrawn) {
case(11) : printf("%s\n", "Jack");
points[ACELOW] += 10;
points[ACEHIGH] += 10;
break;
case(12) : printf("%s\n", "Queen");
points[ACELOW] += 10;
points[ACEHIGH] += 10;
break;
case(13) : printf("%s\n", "King");
points[ACELOW] += 10;
points[ACEHIGH] += 10;
break;
default : points[ACELOW] += cardDrawn;
if (cardDrawn == 1)
{
printf("%s\n", "Ace");
points[ACEHIGH] += 11;
}
else
{
points[ACEHIGH] += cardDrawn;
printf("%d\n", cardDrawn);
}
} return;
}
/*** Figure the total for player or dealer to see who won. This function takes into account the fact that Ace is either 1 or 11. ***/
void totalIt(int points[2], int total[2], int who)
{
/* The following routine first looks to see if the total points counting Aces as 1 is equal to the total points couning Aces as 11. If so,
or if the total points counting Aces as 11 is more than 21, the program uses the total with Aces as 1 only */
if ((points[ACELOW] == points[ACEHIGH]) || (points[ACEHIGH] > 21)) {
total[who] = points[ACELOW]; /* Keeps all Aces as 1 */
}
else {
total[who] = points[ACEHIGH]; /* Keeps all Aces as 11 */
}
if (who == PLAYER) /* Determines the message printed */ {
printf("You have a total of %d\n\n", total[PLAYER]);
}
else {
printf("The house stands with a total of %d\n\n", total[DEALER]);
}
return;
}
/*** Prints the winning player. ***/
void findWinner(int total[2])
{
if (total[DEALER] == 21) {
printf("The house wins.\n");
return;
}
if ((total[DEALER] > 21) && (total[PLAYER] > 21)) {
printf("%s", "Nobody wins.\n");
return;
}
if ((total[DEALER] >= total[PLAYER]) && (total[DEALER] < 21)) {
printf("The house wins.\n");
return;
}
if ((total[PLAYER] > 21) && (total[DEALER] < 21)) {
printf("The house wins.\n");
return;
}
printf("%s%c", "You win!\n", BELL);
return;
}
/*** Gets the user's uppercase, single-character response. ***/
char getAns(char mesg[])
{
char ans;
printf("%s", mesg); /* Prints the prompt message passed */
ans = getchar();
getchar(); /* Discards newline. You can safely ignore compiler warning here. */
return toupper(ans);
}
/*** Clears everything off the screen. ***/
void dispTitle(void)
{
int i=0;
while (i < 25) { /* Clears screen by printing 25 blank lines to 'push off' stuff that
might be left over on the screen before this program */
printf("\n");
i++;
}
printf("\n\n*Step right up to the Blackjack tables*\n\n");
return;
}
Upvotes: 3
Views: 3362
Reputation: 61986
"H"
(in double quotes) is a string, not a character. To get a character constant containing the letter H
, you need 'H'
(in single quotes.) So, your line should read if( ans == 'H' )
.
What will also work is if( ans == "H"[0] )
. This will compare ans
against the first (zero-th) character of the string "H"
.
I agree that this is an insanely cryptic message for a simple type mismatch error. Blame it on C and C compilers. (May I suggest that you use some more modern language like C# or Java?)
The compiler reports your ans
as an int
while you may have declared it as a char
. (I do not know how you have declared it, because you seem to have omitted its declaration from the source code that you posted.) If that is happening, it is because the compiler implicitly converts the char
to int
while trying to compare it with something else.
The compiler also reports your "H"
as a char[2]
, and it might not be immediately obvious why: C uses null-terminated strings, so the literal "H" is represented as a 2-character array, where the first character is 'H'
and the second character is the null character. ('\0'
).
And then the compiler mumbles something about different levels of indirection instead of telling you that the types you are trying to compare are incompatible. That's because in trying to perform the comparison the compiler considers "H"
not as an array of characters, but as a pointer to the first character of the array, but that still does not help, because what it ends up with is a pointer to a character, (one level of indirection,) while it needs a character. (Zero levels of indirection.)
Upvotes: 2
Reputation: 6440
Notice how all of your other comparisons have single quotes?
while (ans == 'Y')
There, you're comparing a single character (which is a number, and thus comparable to another number).
In the code that's failing, on the other hand, you're using double quotes.
ans == "H"
So you're comparing to a string, which is an array of chars. The array is two characters long to accommodate the null terminator.
Upvotes: 5