Sign in to follow this  
Followers 0
benners

Numbers check in C

8 posts in this topic

I am trying to add some error checking in a small program for uni. I have done the program which is just entering a series of number and calculating the average but I also want to add error funtions to check for non mumeric characters.

I have found the isDigit() function but that only checks for 0 - 9, I don't think it would work if 22 or 22.6 was inputted. I am new to C and was wondering if there was anything like isNumber in AutoIt.

Thanks

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Write your own.

Just enumerate all characters and check to see if it's 0-9 or '.'.

bool IsNumber(char *text)
{
    for (int i = 0; text[i] != 0; i++)
    {
        if (!(('0' <= text[i] && text[i] <= '9') || text[i] == '.'))
            return false;
    }
    return true;
}

Edit: Just to make it clear, this code expects a null terminated string.

Edited by Richard Robertson

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

That code is needlessly confusing:

  • You've flipped the lvalue and rvalue in one of the tests making it inconsistent.
  • There are two <= tests (due to the flipped values) which is just horribly confusing.
  • For some reason the code negates the tests instead of just using the correct operators to start with.
This is a hell of a lot easier to follow:

bool IsNumber(char *text)
{
    for (int i = 0; text[i] != 0; i++)
    {
         if ((text[i] < '0' || text[i] > '9') && text[i] != '.'))
             return false;
     }
     return true;
}
Edited by Valik

Share this post


Link to post
Share on other sites

Yeah my bad. I've had a long day and I apparently shouldn't be coding right now.

Share this post


Link to post
Share on other sites

While you're at it, should probably add a buffer length parameter in there to be safe and avoid possible buffer overruns from bad input strings.

If the OP wants to take it a step further, he should also test for only one occurrance of a '.', an allowance for scientific notation (2.53E4), and '-' for negative numbers and exponents.

Share this post


Link to post
Share on other sites

Thanks all for the responses and suggestions. I have finished the other questions I had and will play around with the answers you have all provided. :)

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Still, you need a boolean variable to see if it's not something lime 1.1.2 as wraithdu pointed:

#include <iostream>
using namespace std;

bool IsNumber(char*);

int main()
{
    char num[] = "123456789", anum[] = "12345.00lk";

    cout << "num is ";
    if (IsNumber(num))
        cout << "a number\n";
    else    
        cout << "not a number\n";

    cout << "anum is ";
    if (IsNumber(anum))
        cout << "a number\n";
    else
        cout << "not a number\n";

    return 0;
}

bool IsNumber(char *text)
{
    char *lpstr = text-1;
    
    while (*++lpstr)
         if ((*lpstr > '9' || *lpstr < '0') && *lpstr != '.')
             return false;
     return true;
}
Edited by Authenticity

Share this post


Link to post
Share on other sites

There are other ways to do this, without catching a few false positives, like "10.10.42.22". One way is to use sscanf. Keep in mind that bool and cout are part of C++, not C.

#include <stdio.h>

int IsNumber(const char *text) {
    double result;
    char c = '\0';

    /* returns true (1) if there is only one value read (the float). */
    /* returns false (0) if nothing valid was read or if a character followed the floating point value. */
    if (sscanf(text, "%lf%c", &result, &c)==1) {
        return 1;
    }
    else if (c == '\0') {
        /* if c has only a null character, then the string did actually end in the correct spot. */
        return 1;
    }
    else {
        return 0;
    }
}

Another way is to create an interpreter function to read the input string and rejects if the string is not ended by the time the number is finished. I have not included the parts that actually determine the value, just valid syntax.

#include <assert.h>
#include <ctype.h>

int IsNumber(const char *text) {
    char *ptr=text;   /* a pointer to keep track of where in the string we are looking */
    
    /* check for a sign */
    if (*ptr == '-' || *ptr == '+') {
        ++ptr;
    }
    /* Read the part in front (whole number) portion of the string;
    while (isdigit(*ptr)) {
        ++ptr;
    }
    if (*ptr == '.') {
        /* found the decimal point.  Move on to the next part */
        ++ptr;
    }
    /* other characters will actually get trapped later. */
    /* read the decimal (fractional) portion */
    while (isdigit(*ptr)) {
        ++ptr;
    }
    /* String should end, or may be followed by exponent portion, the E-42 part. */
    if (*ptr == '\0') {
        /* end of string.  Valid exit point. */
        return 1;
    }
    else if (toupper(*ptr) != 'E') {
        /* nothing else is valid.  Return false. */
        return 0;
    }
    /* Exponent portion */
    assert(*ptr == 'e' || *ptr == 'E');
    ++ptr;
    if (*ptr == '-' || *ptr == '+') {
        ++ptr;
    }
    while (isdigit(*ptr)) {
        ++ptr;
    }
    /* This has to be the end of the string. */
    if (*ptr == '\0') {
        /* end of string.  Valid exit point. */
        return 1;
    }
    else {
        return 0;
    }
}

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0