0

I have the following code in C:

#include "stdafx.h"
#include <stdlib.h>
#include <cstring>
#include <ctype.h>

int main()
{
    char buffer[20];
    int num;
    bool valid = true;

    printf("Please enter a number\n");
    fgets(buffer, sizeof(buffer), stdin);
    printf("\n\n");

    if(!isdigit(buffer[0])) //Checking if the first character is -
    {
        if(buffer[0] != '-')
        {
            valid = false;
        }

        else
        {
            if(!isdigit(buffer[1]))
            {
                valid = false;
            }
        }
    }

    char *pend = strrchr(buffer, '\n'); //Replacing the newline character with '\0'

    if (pend != NULL)
    {
        *pend = '\0';
    }

    for (int i = 1; i < strlen(buffer); i++) //Checking that each character of the string is numeric
    {
        if (!isdigit(buffer[i]))
        {
            valid = false;
            break;
        }
    }

    if(valid == false)
    {
        printf("Invalid input!");
    }

    else
    {
        num = atoi(buffer);
        printf("The number entered is %d", num);
    }
    getchar();
}

Basically, the code ensures that the user input is a positive or negative whole number. No letters, floating point numbers etc. are allowed.

The code works perfectly and does its job well.

However, the code is too long and I have to implement it in a number of programs. Is there a simple way to perform all of the above in C? Maybe a shorter alternative that ensures that the input is:

i) not a letter ii) a positive or negative WHOLE number

6
  • Put it all in a reusable function. Include that file in your various projects. You could likely shrink the code as well but I'm too lazy to read it all when the obvious solution is to make what you have reusable. Commented Mar 5, 2013 at 20:22
  • 1
    Use the standard library. strtol does all of this. Commented Mar 5, 2013 at 20:22
  • @n.m. strtol() doesn't return errors properly. Commented Mar 5, 2013 at 20:24
  • @AlexeyFrunze: strtol returns everything you need, just use it properly. Commented Mar 5, 2013 at 20:26
  • @n.m. Ah, I missed the part about errno being set to ERANGE when the number is too big/small. But then, I'm not sure if it sets errno to something when the input is not a valid number, you cannot use the return value of 0 to distinguish between 0 and an error. Commented Mar 5, 2013 at 20:33

2 Answers 2

1
bool valid = false;
char *c = buffer;
if(*c == '-'){
   ++c;
}
do {
   valid = true;
   if(!isdigit(*c)){
      valid = false;
      break;
   }
   ++c;
} while(*c != '\0' && *c != '\n');

Note: this will not handle hex values, but will pass octal (integers starting in 0)

I also have to agree that this should be placed in a common library and called as a function.

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

6 Comments

You never set valid to true. Also, bool, true and false should come from a header or a definition.
changed to intialize to true. and yes you should include stdbool.h to declare bool, true, and false.
@Alexey Frunze Feel free to write a full regression suite if you feel one is needed.
The code checks for '-' to see if the user entered a negative number
Alexey's concern was the the string "-" (with no digits following - would be detected as a number. I have updated the code to avoid that.
|
0

Although some people have pointed out that strtol may not give you the errors you need, this is a very common type of thing to do, and therefore it does exist in the standard library:

http://www.cplusplus.com/reference/cstdio/sscanf/

#include <stdio.h>

// ....

valid = sscanf (buffer,"%d",&num);

Another comment is that you should not be afraid of writing complicated and useful code, and modularizing it. Create a library for the input parsing routines you find useful!

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.