I have a function to validate data from stdin, i want to get only integers. It works when I input letters, but it doesn't work with decimal numbers. n becomes 1, but I get digits before '.', and stdin doesn't clear.
#include <stdio.h>
int get_Int(int *a) {
int n;
do {
n = scanf("%d", a);
if (n == 0) {
printf("Incorrect input. Try again!\n");
scanf("%*f^\n");
scanf("%*s");
continue;
}
} while(n == 0);
return n < 0 ? 0 : 1;
}
int main() {
int n, t;
get_Int(&n);
for (int k = 0; k < n; k++) {
printf("Input next number\n");
get_Int(&t);
printf("%d\n", t);
}
}
example screenshot:
What shall I add to make it work correctly? Or another solution?
you should use strtol or friends (code mostly inspired from man strtol and getline):
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int get_Int(int *a)
{
if (!a)
return 0;
while (1) {
char *line = NULL, *endptr = NULL;
size_t len = 0;
ssize_t nread = getline(&line, &len, stdin);
long n;
if (nread == -1)
continue; // read failed
errno = 0; /* To distinguish success/failure after call */
n = strtol(line, &endptr, 10 /* assuming base10 */ );
/* Check for various possible errors */
if ((errno == ERANGE && (n == LONG_MAX || n == LONG_MIN))
|| (errno != 0 && n == 0)) {
printf("number out of range, please retry\n");
continue; // over/under flow
}
if (endptr == line || *endptr != '\n') {
// No digits were found or not all input was consumed
printf("Please input integers\n");
continue;
}
*a = n;
free(line);
break;
}
return 1;
}
int main()
{
int n, t;
get_Int(&n);
for (int k = 0; k < n; k++) {
printf("Input next number\n");
get_Int(&t);
printf("%d\n", t);
}
}
This implies you should read the line separately and extract the value after. You may notice that there are a lot of checks to perform for the validity of the call, and the hunk of code here is far from perfect, there would be some clarification needed on return values of you function...