Reputation: 11
int main() {
int choice;
printf("\n----------Welcome to Coffee Shop----------");
printf("\n\n\t1. Login ");
printf("\n\t2. Sign Up ");
printf("\n\nPlease enter 1 or 2: ");
scanf(" %d", &choice);
system("cls||clear");
//put while loop to check
switch (choice) {
case 1:
system("cls||clear");
login();
break;
case 2:
system("cls||clear");
user_signup();
break;
default:
printf("\nInvalid Number\n");
main();
break;
}
return 0;
}
How do i make user retype their input if the input is not int? I tried to use isdigit() but it wont work, May i know what are the solutions?
Upvotes: 0
Views: 90
Reputation: 11
I think it would be better to receive it as a string and check if all chars are numbers. And if all the chars are numbers, they convert them to int
like this
int main() {
int choice;
char chars[100];
printf("\n----------Welcome to Coffee Shop----------");
printf("\n\n\t1. Login ");
printf("\n\t2. Sign Up ");
printf("\n\nPlease enter 1 or 2: ");
scanf(" %s", chars);
choice = stringToInteger(chars);
system("cls||clear");
//put while loop to check
switch (choice) {
case 1:
system("cls||clear");
login();
break;
case 2:
system("cls||clear");
user_signup();
break;
default:
printf("\nInvalid Number\n");
main();
break;
}
return 0;
}
int stringToInteger(char* chars)
{
int i = 0, number = 0;
while(chars[i] >= '0' && chars[i] <= '9')
{
number = chars[i++] - '0' + number * 10;
}
return number;
}
Upvotes: 1
Reputation: 154312
scanf(" %d", &choice);
fails to handle cases where the converted input is outside the int
range. That leads to undefined behavior.
Drop using scanf()
.
Use fgets()
to read a line of user input into a string, then validate.
For str2subrange()
, see Why is there no strtoi
in stdlib.h
?.
bool validate_int(const char *s, int *value) {
const int base = 10;
char *endptr;
errno = 0;
long lvalue = str2subrange(s, &endptr, base, INT_MIN, INT_MAX);
// For OP's case, could instead use
long lvalue = str2subrange(s, &endptr, base, 1, 2);
if (value) {
*value = (int) lvalue;
}
if (s == endptr) {
return false; // No conversion
}
if (errno == ERANGE) {
return false; // Out of range
}
// Skip trailing white-space
while (isspace(((unsigned char* )endptr)[0])) {
endptr++;
}
if (*endptr != '\0') {
return false; // Trailing junk
}
return true;
}
Upvotes: 1
Reputation: 465
Instead of the recursive call to main()
you should use a loop. Also consider getchar()
instead of scanf
for single character input. For example, the following will do what you want.
#include <stdio.h>
#include <stdlib.h>
int main() {
int valid_choice = 0;
while (!valid_choice) {
printf("\n----------Welcome to Coffee Shop----------");
printf("\n\n\t1. Login ");
printf("\n\t2. Sign Up ");
printf("\n\nPlease enter 1 or 2: ");
char choice = getchar();
system("cls||clear");
//put while loop to check
switch (choice) {
case '1':
valid_choice = 1;
system("cls||clear");
login();
break;
case '2':
valid_choice = 1;
system("cls||clear");
user_signup();
break;
default:
printf("\nInvalid Number\n");
break;
}
}
return 0;
}
Upvotes: 0
Reputation: 3396
The scanf()
function returns the number of fields that were successfully converted and assigned. So in your scanf(" %d", &choice);
line, you can do this:
do {
printf("\n\nPlease enter 1 or 2: ");
int result=scanf(" %d", &choice);
if (result==1) {
break;
}
printf("\nInvalid Number\n");
} while (1);
Upvotes: 0
Reputation: 44340
scanf
returns the number of input items successfully matched. So you can build a loop that runs until you get exactly one item.
A very simple approach would be:
while(1)
{
int res = scanf(" %d", &choice);
if (res == 1) break; // Done... the input was an int
if (res == EOF) exit(1); // Error so exit
getchar(); // Remove an discard the first character in stdin
// as it is not part of an int
}
printf("Now choice is an int with value %d\n", choice);
That said, I recommend that you take a look at fgets
and sscanf
. They are often a better approach than scanf
Upvotes: 1