1

EDIT: Thank you very much for the detailed responses Trying to program in C. I included the 'ctype.h' and 'stdio.h' libraries. I get the program to prompt the user for a number with 'printf', but when i try to store it with 'scanf' it seems to crash at that point in the program. Is there anything special I should check, because I really just downloaded and installed codeblocks, assuming it would work. Please help.

Here is my code:

#include <stdio.h>
#include <ctype.h>
main()
{
   int userNumber = 0;
   int correctNumber = 0;

   correctNumber = (rand() % 10) + 1;
   printf("Pick a number between 1 and 10");
   scanf("%d", &userNumber);

   if (isdigit(userNumber)) {
     if (userNumber == correctNumber) {
        printf("Yay, you guessed it!");
     }
     else {
        printf("Wrong Number!!!");
     }
   }
   else {
      printf("That is not a number from 1 - 10");

   }
}
austin robinson
  • 51
  • 1
  • 1
  • 6
  • 3
    Please re-read the [documentation](http://www.cplusplus.com/reference/cctype/isdigit/) of `isdigit`. You're using it wrong. – abelenky Jul 20 '13 at 15:38
  • Not that this will solve the problem but `main` is typically declared as `int` and should also return something (like 0). Did codeblocks complain about the lack of return type? – Nobilis Jul 20 '13 at 15:40
  • 1
    `#include ` for `rand`, `isdigit(userNumber -1 + '0')` – BLUEPIXY Jul 20 '13 at 16:49
  • @Nobilis any function without a return is implicitly int. – TheBlueCat Jul 20 '13 at 17:58
  • @TheBlueCat There is a reason why `main` should be explicitly declared as `int` and return something. The C99 for example requires that `main` be int. More [here](http://stackoverflow.com/questions/204476/what-should-main-return-in-c-c). – Nobilis Jul 21 '13 at 02:29
  • @Nobilis I am well aware of that. He did not specify his compile flags, thus it was safe to assume he did not compile with C99 in mind. Moreover, the standard (c99) as you rightly said forbids main not being explicitly defined as non-int -- I doubt that the 'bug' is the return type, that only satisfies the environment the processes is in. – TheBlueCat Jul 21 '13 at 12:11
  • @TheBlueCat I didn't say anywhere it was the issue, the comments section is intended for suggestions or clarifications, my comment was the former. – Nobilis Jul 21 '13 at 12:25

6 Answers6

2

isdigit function checks whether parameters is a decimal digit character .
If you want to work that way, just cast it :

if (userNumber == correctNumber)

to

if (isdigit(userNumber + (char)'0'))

The statement that follows the word else is executed only if the expression in parentheses has the value 0 .
If return value of isdigit function is true (not be 0), next line of your code will be executed .
Under the debugger it looks like this :

CPU Disasm
Address   Hex dump          Command                             Comments
00401048  |.  68 24504200   push offset t3.00425024             ; /format = "%d"
0040104D  |.  E8 E3070000   call t3.scanf                       ; \scanf - Read your integer variable and store it to int
00401052  |.  83C4 08       add esp,8                           ; 
00401055  |.  8B45 F8       mov eax,dword ptr [ebp-8]           ; Store userNumber in eax (5 in this case)
00401058  |.  83C0 30       add eax,30                          ; 5 + 0x30 = 0x35 = Character 0, so decimal number is converted to char value 5
0040105B  |.  50            push eax                            ; /c => 48., stack it
0040105C  |.  E8 E6020000   call t3.isdigit                     ; execute isdigit function - if (isdigit(userNumber+(char)'0'))
00401061  |.  83C4 04       add esp,4                           ; adjust stack
00401064  |.  85C0          test eax,eax                        ; isdigit returned result is 0  ?
00401066  |.  74 37         jz short t3.0040109F                ; if result is NOT 0, next line will be executed
00401068  |.  8B4D F8       mov ecx,dword ptr [ebp-8]           ; ecx = userNumber
0040106B  |.  3B4D FC       cmp ecx,dword ptr [ebp-4]           ; if (userNumber == correctNumber) 
0040106E  |.  75 0F         jne short t3.0040107F               ; if condition is TRUE - statement1 will be executed, otherwise statement2 
00401084  |.  E8 22080000   call t3.printf                      ; printf("Yay, you guessed it!");
....
00401081  |.  E8 25080000   call t3.printf                      ; printf("Wrong Number!!!");
.....
0040109F  |.  E8 05080000   call t3.printf                      ; printf("That is not a number from 1 - 10");

As seen below, expression is 0, and statement that follows else always will be executed eg.printf("That is not a number from 1 - 10");
Your initial code looks like this :

Address   Hex dump          Command                        Comments
0040104D  |.  E8 E3070000   call t3.scanf                  ; \scanf
00401052  |.  83C4 08       add esp,8                      ; 
00401055  |.  8B45 F8       mov eax,dword ptr [ebp-8]      ; eax is now 5, but this time the conversion is not made
00401058  |.  50            push eax                       ; /c => 5 
00401059  |.  E8 E9020000   call t3.isdigit                ; \isdigit
.....
00401061  |.  85C0          test eax,eax                   ; isdigit returned 0 this time
00401063  |.  74 37         jz short t3.0040109C           ; well, jump to last printf
.....
0040109C  |.  E8 05080000   call t3.printf                 ; \printf("That is not a number from 1 - 10");

If use ((char) userNumber + '0'), result will be the same. Only instruction which gets the value will be changed to movsx eax, byte ptr [ebp-8] .

boleto
  • 1,149
  • 1
  • 22
  • 32
0

make the below changes

 if (isdigit((char)userNumber+'0'))

The program works perfectly fine in gcc , use stdlib.h for rand function

Santhosh Pai
  • 2,535
  • 8
  • 28
  • 49
0

Instead of: if(isdigit(userNumber))

write this: if((userNumber>0)&&(userNumber<=10))

0
#include <stdio.h>
#include <ctype.h>
main()
{
    char userNumber = 0; // isdigit can only be used on char
    int correctNumber = 0;

    correctNumber = (rand() % 10) + 1;
    printf("Pick a number between 1 and 10");
    scanf("%c", &userNumber);

    if (isdigit(userNumber)) {
        if ((userNumber-'0') == correctNumber) { // Convert userNumber to int
            printf("Yay, you guessed it!");
    }
    else {
        printf("Wrong Number!!!");
    }
    }
    else {
        printf("That is not a number from 1 - 10");
    }
}

Plus, isdigit() can only be used to detect char from 0-9. In your code 10 will not be correctly identified.

AuA
  • 481
  • 1
  • 5
  • 11
0

I've added some exit codes for the different situations where input is not as expected and some further validation (in addition to fixing the return type of main). I also hardcoded the correctNumber value for easier testing.

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

int main() /* let's fix the signature for main */
{
    char userNumber [10]; /* as we need to pass a char array let's change the type for userNumber */
    int correctNumber = 0;

    correctNumber = 5;/*(rand() % 10) + 1; - I've hardcoded this just for the sake of testing */
    printf("Pick a number between 1 and 10: ");
    scanf("%s", userNumber);

    /* I've updated the if a bit to check separately for range and whether input is a valid number */

    if (isdigit(userNumber[0]))
    {
        int inputtedNumber = atoi(userNumber); /* convert string to int */

        if (inputtedNumber <= 10 && inputtedNumber > 0) {
            if (inputtedNumber == correctNumber) {
                printf("Yay, you guessed it!\n");
                exit(0); /* exit is used to indicate the execution status to the environment (successful or if not how it failed */
        `    }
            else {
                printf("Wrong Number!!!\n");
                exit(1);
            }
        }
        else {
            printf("You've not inputted a number between 1 and 10.\n");
            exit(2);
        }
    }
    else {
        printf("You've not inputted a valid number.\n");
        exit(3);
    }
}

Let me know if something is not clear.

Nobilis
  • 7,310
  • 1
  • 33
  • 67
-1

the function "int isdigit(int c);" is "Checks whether c is a decimal digit character."

So change you code like this :

scanf("%d",&userNumber)

==>

scanf("%c",&userNumber);

it will work as expect!

add this:

if(uerNumber == currentNumber)

==>

if((userNUmber - '0') ==currentNumber)

And can you gave my reputation back? I answer your question at 3 am and just a little sleepy

Lidong Guo
  • 2,817
  • 2
  • 19
  • 31
  • No, it will not work after this fix, because `correctNumber` will still be an int (1-10), and not a char. – abelenky Jul 20 '13 at 22:15
  • @abelenky Hi, I just leaved shool one month ago, working at a game company. We use Linux and C. Most of the time I reading other peoper's – Lidong Guo Jul 21 '13 at 02:24
  • @abelenky Most of the time I only need reading otherr peoper's code and do some porting thing.It's borng. So would you like to give me some suggestion ,like how to improve myself?Hope for you advising – Lidong Guo Jul 21 '13 at 02:33