I've just started learning how to program in C, I'm not able get rid of the error. Here's my program:
/* This program rolls two dice and presents the total. It then asks the user
to guess if the next total will be higher, lower, or equal. It then rolls
two more dice and tells the user how they did. */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int dice1, dice2, total, total1= 0;
char ans[25], dans[25];
char higher[] = "HIGHER", lower[] = "LOWER", equal[] = "EQUAL";
//the following 3 lines, throws the dice and adds them.
dice1 = (rand() % 5) + 1;
dice2 = (rand() % 5) + 1;
total = dice1 + dice2;
//the next few ask the question.
printf("Will the next number be higher, lower or equal to %d ?\n", total);
puts("Type higher, lower or equal.");
// scanf("&s", ans); //had to remove this line, because apparently we can't use &s to get the string input
fgets(ans, 25, stdin);
strcpy(dans, strupr(ans));
//the next few throw the dice two more times
dice1 = (rand() % 5) + 1;
dice2 = (rand() % 5) + 1;
total1 = dice1 + dice2;
/*All of these check if the user input matches the actual output and
then tells the user if he/she was right.*/
printf("The upper string is %s.\n", ans);
if ((ans == higher) && (total1 > total))
{
printf("You're right, it is higher!\n");
}
else if ((ans == lower) && (total1 < total))
{
printf("You're right, it is lower!\n");
}
else if ((ans == equal) && (total1 = total))
{
printf("You're right. they are equal!\n");
}
else
{
printf("Your prediction was wrong.\n");
}
}
The errors which I'm getting:
test.c:25:22: error: implicit declaration of function 'strupr' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
strcpy(dans, strupr(ans)); ^
test.c:25:22: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *' [-Werror,-Wint-conversion]
strcpy(dans, strupr(ans)); ^~~~~~~~~~~
/usr/include/string.h:129:70: note: passing argument to parameter '__src' here extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^
test.c:33:18: error: array comparison always evaluates to false [-Werror,-Wtautological-compare]
if ((ans == higher) && (total1 > total)) ^
test.c:37:23: error: array comparison always evaluates to false [-Werror,-Wtautological-compare]
else if ((ans == lower) && (total1 < total)) ^
test.c:41:23: error: array comparison always evaluates to false [-Werror,-Wtautological-compare]
else if ((ans == equal) && (total1 = total))
Please help me with the errors.
Also,
strupr is supposed to be there in stdlib
, why am I still getting an error?
When I convert a string to an uppercase string how does it change to int?
Why am I not able to use %s
in scanf
? (I have used this before)
Thank you.
[answering one question of the this multi-question question]
Why am I not able to use %s in scanf?
You can, but in fact you use &s
// scanf("&s", ans); //had to remove this lin
which not the same as %s
.
You have a number of issues to address. Your use of strupr
is not a standard C function and may only be available on windoze. Your alternative that are standard are to write a short function and either use the functions isupper()
or islower()
from the header <ctype.h>
to loop over each character and calling toupper()
if a change from lower-case to upper-case is required.
A short function can do all of that for you in a very efficient manner. Something like:
/** convert string to uppercase.
* returns string with all chars converted to uppercase.
*/
char *str2upper (char *str)
{
if (!str) return NULL;
char *p = str;
for ( ; *p; p++)
if ('a' <= *p && *p <= 'z')
*p += 'A' - 'a';
return str;
}
is all you need. It simply walks the string provided as input and if the character is lowercase, converts it to uppercase.
Your next problem is how you handle the buffer filled by fgets
. Being a line-oriented input function, it will read up to and including the '\n'
at the end of the input, including that as your final character in asn
. Now no matter what you do with your conversion, dans
will never match higher
or lower
or equal
-- you figure out why yet?
Let's look at your `higher'
'H','I','G','H','E','R'
Now lets look at dans
if it contained the same word (but with the '\n'
character still dangling off the end):
'H','I','G','H','E','R','\n'
Since you read with fgets
and did not remove the trailing '\n'
, it will always prevent a valid comparison between dand
and any of your strings. How to fix it?
Simple, just check that the last character in the ans
as filled by fgets
is the '\n'
and overwrite the '\n'
with a nul-terminating character removing it. (additionally, you should check that the user didn't cancel the input by generating a manual EOF
to quit early. You can do all those things in a simple little input loop while requiring your user to enter a valid string until he does or decides to cancel, e.g.
if (!fgets (ans, 25, stdin)) { /* check for user cancle with EOF */
fprintf (stderr, "user canceled input.\n");
return 1;
}
size_t len = strlen (ans); /* get string length */
if (len && ans[len - 1] == '\n') /* valisate last char is '\n' */
ans[--len] = 0; /* overwrite with nul-character */
else /* warn if chars can remain unread (input too long) */
fprintf (stderr, "unread characters may remain in stdin.\n");
strcpy(dans, str2upper(ans));
Now dans
is properly uppercase and has no '\n'
dangling off its tail-end.
Your comparisons are the last problem area. You cannot check string equality with the ==
operator. (that is for comparing a character at a time, not a string. The strcmp
function in string.h
is the proper tool here. If the strings compare equally, strcmp
returns 0
. With that in mind you can fix your comparisons with:
/*All of these check if the user input matches the actual output and
then tells the user if he/she was right.*/
printf("The upper string is %s.\n", ans);
if (strcmp (dans, higher) == 0 && (total1 > total))
{
printf("You're right, it is higher!\n");
}
else if (strcmp (dans, lower) == 0 && (total1 < total))
{
printf("You're right, it is lower!\n");
}
else if (strcmp (dans, equal) == 0 && (total1 == total))
{
printf("You're right. they are equal!\n");
}
else
{
printf("Your prediction was wrong.\n");
}
Now putting it altogether, you have your code in a form that should work, e.g.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/** convert string to uppercase.
* returns string with all chars converted to uppercase.
*/
char *str2upper (char *str)
{
if (!str) return NULL;
char *p = str;
for ( ; *p; p++)
if ('a' <= *p && *p <= 'z')
*p += 'A' - 'a';
return str;
}
int main(void)
{
int dice1, dice2, total, total1= 0;
char ans[25] = {0}, dans[25] = {0};
char higher[] = "HIGHER", lower[] = "LOWER", equal[] = "EQUAL";
//the following 3 lines, throws the dice and adds them.
dice1 = (rand() % 5) + 1;
dice2 = (rand() % 5) + 1;
total = dice1 + dice2;
//the next few ask the question.
printf("Will the next number be higher, lower or equal to %d ?\n", total);
fputs ("Type higher, lower or equal: ", stdout);
if (!fgets (ans, 25, stdin)) { /* check for user cancle with EOF */
fprintf (stderr, "user canceled input.\n");
return 1;
}
size_t len = strlen (ans); /* get string length */
if (len && ans[len - 1] == '\n') /* valisate last char is '\n' */
ans[--len] = 0; /* overwrite with nul-character */
else /* warn if chars can remain unread (input too long) */
fprintf (stderr, "unread characters may remain in stdin.\n");
strcpy(dans, str2upper(ans));
//the next few throw the dice two more times
dice1 = (rand() % 5) + 1;
dice2 = (rand() % 5) + 1;
total1 = dice1 + dice2;
/*All of these check if the user input matches the actual output and
then tells the user if he/she was right.*/
printf("The upper string is %s.\n", ans);
if (strcmp (dans, higher) == 0 && (total1 > total))
{
printf("You're right, it is higher!\n");
}
else if (strcmp (dans, lower) == 0 && (total1 < total))
{
printf("You're right, it is lower!\n");
}
else if (strcmp (dans, equal) == 0 && (total1 == total))
{
printf("You're right. they are equal!\n");
}
else
{
printf("Your prediction was wrong.\n");
}
}
Example Use/Output
$ ./bin/rolldice
Will the next number be higher, lower or equal to 6 ?
Type higher, lower or equal: lower
The upper string is LOWER.
You're right, it is lower!
Look things over and let me know if you have additional questions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With