Test if a string is a number
int test and double test are incompletely done.

errno = 0;
long val = strtol(argv[1], &amp;p, 0);
if (errno) Fail();         // Range error (or possible other reasons)
if (argv[1] == p) Fail();  // no conversion
while (isspace((unsigned char) *p)) p++;
if (*p) Fail();            // Extra junk afterwards


if (*p) Fail(); Needs to be applied to both integer and FP test.

while (isspace((unsigned char) *p)) p++; allows trailing white-space.  Both strtol() and strtod() allow leading white-space.

Double is more complex as in the case of underflow like "1e-10000", the errno may set and that is usually not considered an error in many uses.  The returned value will be either +/-0.0 or a small double value.

double val2 = strtod(argv[1], &amp;p);
if (errno == ERANGE &amp;&amp; fabs(val2) &lt;= DBL_MIN) NoFail();


Keep in mind a string may nicely translate to a long as well as a double.  Should "-0" be along 0 or double -0.0?  Aside from this case, I would favor long, especially if the test for extra junk is used.

Your test cases do not include big values "123...thousand_more...456", values like LONG_MIN (-1, +0, +1) and  LONG_MAX (-1, +0, +1), DBL_MAX, next_after(DBL_MAX,0), strings with trailing garbage "123xyz", -0.0.  BTW: a harsh check it to use (char) -1 in various places in the string. Or lead the string with (char) (x80 + ' ')

Nor does it test odd things like "++123", "0x0xABC", "08".  (multiple sign, 2-prefix, octal 8) and new emerging "0b0101"  (C14?)

Extreme FP strings include "0.000...0001e320", "" and "  " (white-space only strings.)

FP also has a hexadecimal format, see scanf("%a")/printf("%a") for additional strings.

Original request was for "double or integer".  Code conveniently uses long, but what if int was meant or intmax_t?  Example additional test for int

long val = strtol(argv[1], &amp;p, 0);
if (val &lt; INT_MIN || val &gt; INT_MAX) RangeError();
int i = (int) val;
...


To cope with decimal separator as , or ., use setlocale() and that will adjust strtol() and strtod().  But that is a weak aspect of C.

Lastly, a given locale could have "additional subject sequences" that convert into numbers.