0

Basically using strtol to check for unsuccessful conversions, I am using the function

width = (int)  strtol(argv[2], NULL, 10);
if (errno != 0) {
    printf("Please parse integer argument");
}

using errno.h

It works when the arguments are characters, i.e.: argv[2] = e, 6, etic But this fails to catch errors when arguments like 444r or 33f (leading numbers followed by characters) are supplied? Is there something I am missing?

mpgn
  • 7,121
  • 9
  • 67
  • 100
Luna
  • 19
  • 1
  • 6
  • 3
    Read the documentation! (Hint: What is that second argument, where you passed `NULL`, for?) – mafso Aug 10 '14 at 21:20
  • Additionally, if you cast to `int` before checking, you cannot catch errors like (e.g. for a platform with 32-bit `int` and 64-bit `long`) an input of 4294967296. – mafso Aug 10 '14 at 21:25
  • Also, you should clear errno before calling strtol(). _The strtol() function shall not change the setting of errno if successful._ – Dipstick Aug 10 '14 at 21:32
  • This has good information as well: http://stackoverflow.com/a/3792676/103167 – Ben Voigt Aug 10 '14 at 21:35
  • @Dipstick: Where is this quote from? `strtol` may change `errno` on success. – mafso Aug 10 '14 at 22:21
  • @mafso: It is part of IEEE Std 1003.1-2001. However the point is that you cannot assume that the value is zero if the conversion succeeded; only that it is non-zero if the conversion failed. – Dipstick Aug 11 '14 at 00:22
  • @Dipstick: Interesting. This seems to be a difference between standard C and POSIX: The former only says that `errno` is set to `ERANGE` if the correct result would over-/underflow, the latter that `errno` is unchanged on success. – mafso Aug 11 '14 at 17:23

2 Answers2

3

You could use the second argument to strtol() to receive a pointer to the first character after the number, and check that the character is NUL (i.e. '\0').

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

You should use the second parameter of the function to determine where the parsing was stopped. According to the C Standard

7 If the subject sequence is empty or does not have the expected form, no conversion is performed; the value of nptr is stored in the object pointed to by endptr, provided that endptr is not a null pointer.

As for errno then

If the correct value is outside the range of representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned (according to the return type and sign of the value, if any), and the value of the macro ERANGE is stored in errno.

It is important to note that if no conversion was done then endptr wilol contain the value of nptr.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335