-3

Is there an elegant way in C to check if a given string is a "double"? Not if the type of the variable is double, but if the string contains a real number. For example:

char input[50];
printf("please enter a real number: \n");
scanf("%s", input);
if ( is_double(input) ) {
    //user entered "2"
    return true;
    //user entered "2.5"
    return true;
    //user entered "83.5321"
    return true;
    //user entered "w"
    return false;
    //user entered "hello world"
    return false;
}
9
  • 4
    You could use strtod and see if it could convert the full string. Commented May 27, 2017 at 16:12
  • 1
    stackoverflow.com/a/456314/971127 Commented May 27, 2017 at 16:16
  • 1
    BTW, fgets(input, sizeof(input)-1, stdin); is better than scanf("%s",input); Commented May 27, 2017 at 16:27
  • The scanf was just for the example, I actually get the string with getchar and reallocate memory as needed. Commented May 27, 2017 at 16:28
  • Compile with all warnings & debug info (e.g. gcc -Wall -Wextra -g with GCC...) then use the debugger gdb and don't forget to read documentation. Commented May 27, 2017 at 16:36

2 Answers 2

1

You need to define if 12 or 1e23 are doubles for you. And what about -4z or 12.3, ? So specify what are acceptable and forbidden inputs (hint: using EBNF on paper could be helpful).


Notice that strtod can be used and can give the pointer to the last parsed character.

So (after adding a #include <stdlib.h> near the beginning of your file ....)

char* endp=NULL;
double x = strtod(input, &endp);
if (*endp == 0) { // parsed a number

Also sscanf (you need to include <stdio.h>) returns the number of scanned items, and accepts %n to give current byte offset.

int pos= 0;
double x = 0.0;
if (sscanf(input, "%f%n", &x, &pos)>=1 && pos>0) { // parsed a number

You could also use regexp (regcomp(3) & regexec(3)...) or parse your string manually

Left as an exercise.

PS. Please read carefully the linked documentations.

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

5 Comments

Trying to use strtod, but for some reason I get x=-var-create: unable to create variable object in the debugger..
I don't understand the above comment. Is your compiler complaining ? And what is var or create ?
The compiler is fine, the variable that get the results of strtod is not set properly. I get this message from the debugger.
Then add a printf or read the documentation of your debugger or lower the optimization level. I still don't understand what is var or create. Your question (and my answer) don't mention it.
Thank you, strtod seems like a good solution, I will check why the variable isn't set properly
1

As long as you aren't allowing scientific notation:

#include <ctype.h>
#include <string.h>
#include <stdbool.h>

bool is_double(const char *input)
{
  unsigned long length = strlen(input);
  int num_periods = 0;
  int num_digits = 0;
  for (unsigned int i = 0; i < length; i++)
  {
    if ( i == 0 )
    {
       if ( input[i] == '-' || input[i] == '+' )
          continue;
    }
    if ( input[i] == '.' )
    {
       if ( ++num_periods > 1 ) return false;
    }
    else
    {
      if (isdigit(input[i]))
      {
         num_digits++;
      }
      else
        return false;
    }
  } /* end for loop */
  if ( num_digits == 0 ) 
      return false;
  else
      return true;
}

1 Comment

Consider replacing if ( num_periods == 0 ) { num_periods = 1; } else return false; with if (num_periods++ != 0) return false;. It's more compact — but doesn't change the functionality. At the moment, the code doesn't handle signs before the number. You explicitly say you don't handle exponents.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.