6

I want to parse an integer but my following code also accepts Strings like "3b" which start as a number but have appended chars. How do I reject such Strings?

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

int main(int argc, char *argv[])
{
    int n;
    if(argc==2 && sscanf(argv[1], "%d", &n)==1 && n>0){
        f(n);
        return 0;
    }
    else{
        exit(EXIT_FAILURE);
    }
}
Gastmon
  • 83
  • 6
  • 4
    You don't use `sscanf()`; you use `strtol()` or similar, and check where the end pointer points. Or, if you must use `sscanf()`, you use `int pos; … if (… && sscanf(argv[1], "%d%n", &n, &pos) == 1)` — note that the `%n` isn't counted as a conversion so the comparison is still against `1`, not `2`. You then check whether `argv[1][pos]` is a null byte or not, complaining if it isn't. – Jonathan Leffler Apr 30 '17 at 20:59
  • http://stackoverflow.com/questions/13199693/what-does-the-n-stand-for-in-sscanfs-d-n-i-n –  Apr 30 '17 at 21:09

2 Answers2

4

For your problem, you can use strtol() function from the #include <stdlib.h> library.

How to use strtol(Sample code from tutorial points)

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

int main(){
   char str[30] = "2030300 This is test";
   char *ptr;
   long ret;

   ret = strtol(str, &ptr, 10);
   printf("The number(unsigned long integer) is %ld\n", ret);
   printf("String part is |%s|", ptr);

   return(0);
}

Inside the strtol, it scans str, stores the words in a pointer, then the base of the number being converted. If the base is between 2 and 36, it is used as the radix of the number. But I recommend putting zero where the 10 is so it will automatically pick the right number. The rest is stored in ret.

Manav Dubey
  • 780
  • 11
  • 26
0

The ctype.h library provides you the function isdigit(char) function that returns whether the char provided as argument is a digit or not.
You could iterate over argv[1] and check it this way.

PMonti
  • 456
  • 3
  • 9
  • Using `isdigit()` is reasonable if only single-digit integers are acceptable. If multi-digit integers are allowed, then `isdigit()` is not such a good solution. It's better to use a string-to-integer conversion function that converts as well as checks (so `strtol()` et al rather than `atoi()`). – Jonathan Leffler Apr 30 '17 at 21:05