0

Hi I have a function here where I just want to input an integer and I am aware that characters can be treated like integers but when scanning I would like to only get integers

fongball
  • 1
  • 2
  • 1
    What is your input? What is your expected output? What is your actual output? – Jabberwocky Sep 28 '17 at 08:10
  • 2
    ... Not directly related: but the recursive call of `setMaxGuess` is fishy. And why do you pass `guessNum` as parameter? – Jabberwocky Sep 28 '17 at 08:11
  • Possible duplicate of [How to clear input buffer in C?](https://stackoverflow.com/questions/7898215/how-to-clear-input-buffer-in-c) – fongball Oct 01 '17 at 22:25

2 Answers2

1

I think you need to read from standard input and reject the data if it is not an integer.

You can check the value returned by scanf() for that. It will be the number of successful assignments.

int rv, c;
rv=scanf("%d", &guessNum);
if(rv!=1)
{
     ///Not an integer
     while((c=getchar())!='\n' && c!=EOF);
}

Here, scanf() would return 1 if it assigned a value to guessNum and otherwise 0 will be returned.

However, if the scanf() didn't assign to guessNum due to incorrect input, that data will remain in the input buffer which must be cleared before reading data entered after that.

The while((c=getchar())!='\n' && c!=EOF); will take care of that.

This might be similar.

Edit: I just saw Michael's comment. You are passing guessNum by value to the function. The changes that you make to this variable won't be reflected to the corresponding variable which calls this function. I can't think of any reason for doing that.

Perhaps you want the changes you make to be reflected back to the original variable. If that's the case, pass the address of the variable to the function (call by reference).

Then the function declaration must be changed to void setMaxGuess(gameState* game, int *guessNum) and you should be passing the address of guessNum with the &guessNum in the function call.

unwind
  • 391,730
  • 64
  • 469
  • 606
J...S
  • 5,079
  • 1
  • 20
  • 35
0

First of all, if you are using recursion you need a proper base case! Moreover, if you want user input at run-time, you shouldn't put the input variable as a parameter to the function.

Instead just use a temporary variable ( as 1. with your current code you cannot pass a constant to the function, 2. passing a global variable will be useless). Now if you use temporary variable, you can keep it static to prevent re-declaration on every recursive call.

Also since you want max guess (not sure), you should also compare maxGuesses with guessNum.

void setMaxGuess(gameState* game){
   static int guessNum;
   // Take input
   if(guessNum < 0)
          //Recurse

   else if(game->maxGuesses > guessNum) 
          //Recurse

   else{ //base case
      game->maxGuesses = guessNum;
      return;
   }          

}

These were some problems with your approach. Now coming to the question of checking if the user has input a valid integer. You can take input as int and check if its not a char. Checking that at run-time can be troublesome (See this).

But, instead you can take the input as char array (string if you will), and loop through it and check using isdigit() from ctype.h

int isnum(char *str)
{
    while (*str)
        if (isdigit(*str++) == 0)
            return 0;
    return 1;
}

and if it is not a number throw error or otherwise convert back to int using atoi() from string.h. Note: If you didn't need 0 as input, you could have just used atoi() to check if a string is a number, as it returns 0 for non-numeric values.

Once you are done, you should be able to do something like this in main():

gameState g1;
g1.maxGuesses = 7; //Setting the initial max value
printf("Initial max value = %d\n", g1.maxGuesses );
setMaxGuess(&g1);
printf("Now the max value = %d\n", g1.maxGuesses );
Akshay
  • 171
  • 1
  • 1
  • 9