1

So I have an IsNumber() function which checks if an user input is a number or not, if it isn't the the program stops, however the function just isn't working for some reason.

Here is where it's implemented:

bool IsNumber(const char* pStr);

int main()
{
    int user;
    char decision;
    char * str[256] = {user};
    bool valid;

    scanf("%d",&user);

    clear_stdin(); // function to remove

    sprintf(str, "%d", user); // to convert input into string so to validate number with function IsNumber

    valid = IsNumber(str);

    if (valid == false)
    {
        printf("Entered input is not a number, exiting now.");
        exit(1);
    }
 }

And here is the function itself:

bool IsNumber(const char* pStr)
{
    if(NULL == pStr || *pStr == "\0")
        return false;

    int dotCount = 0;
    int plusCount = 0;
    int minusCount = 0;

    while (*pStr)
    {
        char c = *pStr;
        switch(c)
        {
        case '.':
             if (++dotCount > 1)
                return false;
             break;
        case '-':
            if (++minusCount > 1)
                return false;
             break;
        case '+':
            if (++plusCount > 1)
               return false;
        default:
            if (c < '0' || c > '9')
                return false;
         }
        pStr++;
    }
    return true;
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • What do you expect to be in `user` when a number is not entered? – stark Apr 04 '20 at 13:37
  • @stark it does not matter. There will be the valid number – 0___________ Apr 04 '20 at 13:39
  • `char * str[256] = { user };` - I strongly suspect that is wrong from inception. Turn up your compiler warnings. The later code using `str` as if it is `char []` and not its actual `char *[]` self (such as the target of a `sprintf`) is a fairly pungent aroma. – WhozCraig Apr 04 '20 at 13:40
  • If `scanf("%d",&user)` [returns](https://en.cppreference.com/w/cpp/io/c/fscanf#Return_value) `1` it's guaranteed that the user entered an integer number, you don't need to convert it to a string and use a second check. – Some programmer dude Apr 04 '20 at 13:42
  • You are converting a string to a number then back to a string to test if its a number. – stark Apr 04 '20 at 13:44
  • How do you know it does not run? Learn how to debug and create a [mre] – klutt Apr 04 '20 at 13:49
  • You want to read [this](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings) before you write another line of C code. – n. m. could be an AI Apr 04 '20 at 14:19
  • Most occurrences of `’+’` are not a digit; you forgot the `break;` after the plus case. Always add the break, even after the last case label in the switch. Also note that you shouldn't accept plus or minus except as the first (none-space?) character. – Jonathan Leffler Apr 04 '20 at 14:51

2 Answers2

1

There are several issues with your code:

The line

char *str[256] = {user};

You are declaring an array of 256 pointers to char, none of them is initialized along your code, so they point to nothing, furthermore you are trying to assign an int variable to a char pointer.

The line

sprintf(str, "%d", user);

str is not a valid argument, you could use str[0], but, again, str[0] points to nowhere.

The line

if(NULL == pStr || *pStr == "\0")
                            ^^^^

You are comparing a single character with a string, a valid comparison would be:

if(NULL == pStr || *pStr == '\0')
                            ^^^^

Other issues are:

  • A missing break in case '+'.
  • char decision is never used.
anastaciu
  • 23,467
  • 7
  • 28
  • 53
1

your function does not check for the most of the errors (for example 345+456). You need to remember that some chars can be only at the particular places to make number valid. Here you have a bit better one (very simple for the sake of simplicity of the answer).

int isNumber(const char *str)
{
    int result = 1;
    int dotFound = 0;
    const char *saved = str;

    if(str || *str)
    {
        while(*str && result)
        {
            if(*str == '-' || *str == '+')
            {
                 if(str != saved) result = 0;
            }
            else
            {
                if(*str == '.') 
                {
                    if(dotFound) result = 0;
                    dotFound = 1;   
                }
                else
                {
                    if(!isdigit(*str)) result = 0;
                }
            }
            str++;
        }
    }
    return result;
}

Your test idea is wrong. sprintf will always print a valid int number. it will also never generate the string with the dot '.' inside.

https://godbolt.org/z/d_Bah9

0___________
  • 60,014
  • 4
  • 34
  • 74