2
votes

Is there a way to use scanf (without using any other I/O function) to check whether the user input exists only of a single integer with nothing following it?

For example:

int g;
while(scanf("%d", &g)!=1){
    printf("\nincorrect input, try again");
}

This works fine for input like "/" or "-" but when you input "54.32" then it will read until the ".", the read count of scanf will be 1 and 54 will be stored in g. Is there a way to check if the input consists solely of a single integer followed by nothing but a newline character?

I would like to know if there exists a solution without using fgets or any other IO function?

3
scanf is for reading formatted input. It is not useful for unformatted entry.stark
"%d%c" and then if the return is 2 and the character isn't '\n' -- extraneous characters exist. (but you really should do all user-input with fgets() and if needed conversions with sscanf())David C. Rankin

3 Answers

2
votes

to check solely of a single integer followed by nothing but a newline character

Use "%n" to record number of characters scanned, if it gets that far.

int n = 0;
scanf("%d*1[\n]%n", &g, &n);
if (n > 0) puts("input consists solely of a single integer followed by a newline");

If the result is not as hoped, additional code needed to cope with the errant input.

I recommend using fgets() to solve the larger problem.

1
votes

Edit because I misunderstood the question: what about this?

#include <stdio.h>

int main() {

    int n;
    char c;

    scanf("%d", &n);

    scanf(" %c", &c) ? printf("incorrect input, try again\n") : printf("%d\n", n);

    return 0;
}
0
votes

You can use the assignment-suppressing format operator to extract everything (anything) after the integer, and the number-of-characters-read format specifier to see whether that matched anything, without having to store it anywhere.

See your documentation.

Eg,

int g, gchars, xchars;
scanf("%d%n%*s%n", &g, &gchars, &xchars);
if (xchars > gchars)
    printf("%d extra characters discarded after integer %d\n", xchars-gchars, g);