5

Is there a function in C to check if the input is an int, long int, or float? I know C has an isdigit() function, and I can create an isnumeric function as follows:

int isnumeric( char *str )
{
    while(*str){
        if(!isdigit(*str))
            return 0;   
        str++;
    }
    return 1;
}

But I was wondering how to create a function that would take a floating point number (as a string) and output a TRUE/FALSE value.

2
  • 1
    you can detect '.' character to determine if its floating point number Commented Jan 4, 2010 at 5:06
  • 2
    Is 42.00000000000000000000000000 a floating point number or an int? And 42.00000000000000000000000001? Commented Jan 4, 2010 at 11:36

3 Answers 3

13

This should do it. It converts the string to floating point using strtod and checks to see if there is any more input after it.

int isfloat (const char *s)
{
     char *ep = NULL;
     double f = strtod (s, &ep);

     if (!ep  ||  *ep)
         return false;  // has non-floating digits after number, if any

     return true;
}

To distinguish between floats and ints is trickier. A regex is one way to go, but we could just check for floating chars:

int isfloat (const char *s)
{
     char *ep = NULL;
     long i = strtol (s, &ep);

     if (!*ep)
         return false;  // it's an int

     if (*ep == 'e'  ||
         *ep == 'E'  ||
         *ep == '.')
         return true;

     return false;  // it not a float, but there's more stuff after it
}

Of course, a more streamlined way to do this is to return the type of the value and the value together.

Sign up to request clarification or add additional context in comments.

4 Comments

Or implement isint() in similar fashion and then, at the end of isfloat, use return !isint(s) instead of return true.
Note that strtod() skips leading white space; so does strtol(). You could decide you don't want that by checking that the first character is not white space explicitly. Alternatively, it would be symmetric to allow trailing white space instead of demanding that the string ends at the end of the number. These are design decisions, not bugs in the code shown.
The end-pointer ep would be equal to s if conversion was not performed, e.g. on a pure alphabet string. See en.cppreference.com/w/cpp/string/byte/strtof. I have used this fact in my real use cases.
This is true for plain c too (if one does not trust the C++ reference for plain c) linux.die.net/man/3/strtod
0
int isnumeric( char *str )
{
    double d;
    return sscanf(str, "%lf", &d);
}

1 Comment

warning: format ‘%g’ expects type ‘float *’, but argument 3 has type ‘double *’
0

If your goal is to find the data type a given string can fit in, you can do something like this:

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

/* If a floating-point number is +/- F_EPS from an integer,
   consider it to be an integer */
#define F_EPS 1e-7

enum datatype {
    TYPE_INT,
    TYPE_LONG,
    TYPE_FLOAT,
    TYPE_DOUBLE,
    TYPE_INVALID
};

enum datatype findtype(const char *s)
{
    char *eptr;
    double d;
    double diff;

    errno = 0;

    d = strtod(s, &eptr);
    if ((d == 0 && eptr == s) || errno == ERANGE)
        return TYPE_INVALID;

    diff = d - floor(d+0.5);
    if (d <= INT_MAX && d >= INT_MIN && diff <= F_EPS)
        return TYPE_INT;

    if (d <= LONG_MAX && d >= LONG_MIN && diff <= F_EPS)
        return TYPE_LONG;

    if ((d > 0 && (d > FLT_MAX || d < FLT_MIN))
                || (d < 0 && (d < -FLT_MAX || d > -FLT_MIN)))
        return TYPE_FLOAT;

    return TYPE_DOUBLE;
}

The idea is that you read the number as a double, and then check to see if it is in the range for different types. You can change F_EPS above to control the tolerance.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.