-1

I need to check whether the input is number. My code looks something like this:

int input;

while ( scanf(" %s %d", string, &input) != EOF) {

if ( isNotANumber(input) ) {
    printf("Not a number"); }

doSomethingElse(input, string);
}

EDIT: I need to be accepting input and calling the function doSomethingElse(input) until the user enters EOF. isNotANumber is a mock function, I don't have that function, I'm asking how could I write it.

EDIT 2: Variable string needs to be a string, variable input needs to be an integer.

EDIT 3: I tried separating my code into this:

while (scanf(" %s", string) != EOF) {
    if (scanf("%d",&input) != 1) {
    printf("not a number");
}
doSomething();
}

But it stil doesn't work for input like "4a".

Kate
  • 45
  • 4
  • 8
  • 1
    I think `isNotANumber(input)` cannot inspect `input` in the loop. – BLUEPIXY Dec 03 '16 at 12:46
  • As `input` is defined `int` its value will always and ever be an integer, at least as long `scanf()` did not fail. – alk Dec 03 '16 at 13:04
  • If you don't know that the input is a number, you cannot use scanf. (Or, rather, you can use scanf, but if scanf doesn't read the input because it isn't a number, then you're going to have to read it some other way, so doing the scanf was pointless.) You'll need to input the data some other way. Try `fread` and then check if it is an integer using `strtol`. BTW, do you mean "number", or "integer"? Be precise. – William Pursell Dec 03 '16 at 13:11
  • Apologies for not clarifying clearly. I've edited my answer. – Kate Dec 03 '16 at 13:23

2 Answers2

1

For example, you can change it as follows.

#include <stdio.h>

#define doSomethingElse(input) do{ printf("your input is %d\n", input); }while(0)

int main(void){
    int input;
    int status;

    while ((status = scanf("%d", &input)) != EOF) {
        if ( status == 0 ) {
            printf("Not a number\n");
            while(getchar() != '\n'); //clear input
        }
        else {
            doSomethingElse(input);
        }
    }
}

However, this can not check input like 123.456. (accept 123)
So, It is recommended to input with fgets and check with strtol.


As already pointed out, like scanf(" %s %d", string, &input) can not check the input after the number.

So, For convenience, check backward input.

char string[32], ch;
int input;
int status;


while ((status = scanf("%31s %d%c", string, &input, &ch )) != EOF) {
    if ( status == 3 && ch == '\n') {
        doSomethingElse(input);
    }
    else {
        printf("Not a number\n");
        while(getchar() != '\n'); //clear input
    }
}

Example using fgets and strtol
(mystrtoi has reorganized the answer of chux. thanks)

#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>

#define doSomethingElse(input) do{ printf("your input is %d\n", input); }while(0)

int mystrtoi(const char *str, int *err) {
    char *endptr;
    *err = errno = 0;
    long l = strtol(str, &endptr, 0);
    if (errno == ERANGE || *endptr != '\0' || str == endptr) {
        *err = 1;
    }
    // Only needed if sizeof(int) < sizeof(long)
    if (l < INT_MIN || l > INT_MAX) {
        *err = 1;
    }
    return (int) l;
}


int main(void){
    char line[128];
    char string1[32], string2[128];
    int num, err;

    while (fgets(line, sizeof line, stdin)){
//      if(2 != sscanf(line, "%31s %31s", string1, string2)){// or use strtok to split
        if(2 != sscanf(line, "%31s %127[^\n]", string1, string2)){
            printf("invalid input\n");
            continue;
        }
        num = mystrtoi(string2, &err);
        if(err) {
            printf("Not a number\n");
        }
        else {
            doSomethingElse(num);
        }
    }
}
Community
  • 1
  • 1
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • Thank you. I've had to edit the code, how can I check my input now? – Kate Dec 03 '16 at 13:20
  • @Kate The situation does not change much. input fails if `status == 1`. – BLUEPIXY Dec 03 '16 at 13:25
  • It still accepts input as "string 4a" and that should also be seen as "Not a number.". How can I fix that? – Kate Dec 03 '16 at 13:29
  • I already recommended to input with `fgets` and check with `strtol`. – BLUEPIXY Dec 03 '16 at 13:31
  • I looked here https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm . But I still don't see how I can use it in my case. Help is greatly appreciated. – Kate Dec 03 '16 at 13:36
  • @Kate validate using `strtol` [string convert to int sample](http://stackoverflow.com/a/22866001/971127) – BLUEPIXY Dec 03 '16 at 13:46
  • The problem is that my scanf functions looks like this: scanf(" %s %d", string, &input). And now I don't know how to adjust it. – Kate Dec 03 '16 at 13:52
  • @Kate Do you necessarily have to use `scanf` ? – BLUEPIXY Dec 03 '16 at 14:04
  • Not necessarily. But I don't know how to use fgets. I've separated my code into this: `while (scanf("%s", string) != EOF) { if (scanf("%d", input) != 1) { printf("Not an integer");} doSomething();}` But it still doesn't work properly for input like 4a. – Kate Dec 03 '16 at 14:56
  • @Kate Sample was added. – BLUEPIXY Dec 03 '16 at 15:24
0
while ( scanf("%d", input) != EOF)

Your scanf code has two problems:

  • scanf returns the number of successfully read item, not EOF. Here you want to check if scanf has successfully read one integer input
  • scanf expects the address of the variable

You should re-write that line as:

while ( scanf("%d", &input) == 1 )
artm
  • 17,291
  • 6
  • 38
  • 54