2

I am trying to create a program which checks if the number user enters is a float, but it does not work. I tried to check with scanf, but that did not work either.

#include <stdio.h>

int main(void) {

        float num1;

        printf("enter number: ");
        scanf("%lf", &num1);



        if (scanf("%lf")) {

                printf("Good \n");
        }
        else {
                printf("Bad \n");
        }
}
4
  • What does it mean to "enter a float"? (Users don't actually enter floats; users enter sequences of characters) Commented Nov 10, 2015 at 2:17
  • scanf is quite dangerous. It is a serious security risk in C (buffer overflow, anyone) and really should be retired. Use getline to get the number as a string and write a function to test and see if it is a valid floating-point number. Commented Nov 10, 2015 at 2:18
  • 1
    @ncmathsadist OP's use of scanf() will not overflow. getline() is not standard C although source code readily available. Agree scanf() source be retired. Commented Nov 10, 2015 at 15:26
  • never heard that scanf is dangerous Commented Nov 4, 2020 at 19:29

2 Answers 2

7

Have you read any documentation on scanf(3)?

You need to check the return value like this

double value;
if (scanf("%lf", &value) == 1)
    printf("It's float: %f\n", value);
else
    printf("It's NOT float ... \n");

There is a way I prefer because it gives more control on subsequent input, scanf() is rarely really useful. Instead try fgets()

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
    char buffer[100];
    double value;
    char *endptr;
    if (fgets(buffer, sizeof(buffer), stdin) == NULL)
        return -1; /* Unexpected error */
    value = strtod(buffer, &endptr);
    if ((*endptr == '\0') || (isspace(*endptr) != 0))
        printf("It's float: %f\n", value);
    else
        printf("It's NOT float ...\n");
} 
Sign up to request clarification or add additional context in comments.

4 Comments

You might want to note how the return value indicates the number of successful assignments, and that a return value of 1 isn't always equivalent to success. My $0.02.
Need to check if (*endptr == buffer) else no conversion occurred. if (*endptr == '\0') typically fails as *endptr --> \n. 2nd half needs work.
@Dogbert I am so tired of writing about it on SO that I left the link so the reader can find out.
I think there's a comma missing before stdin inside the fgets function.
4

The best way to test if a string converts to a double is to use strtod().

strtod() can be tricky to use. With strtod(char *s, char *endptr), if s == endptr, conversion failed. Else check the string starting at endptr for offending characters.

Overflow/underflow issues are not addressed here other than to say strtod() and conversion to float will readily convert to zero or infinity - both which are typically representable as a float.

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

bool is_float(const char *s, float *dest) {
  if (s == NULL) {
    return false;
  }
  char *endptr;
  *dest = (float) strtod(s, &endptr);
  if (s == endptr) {
    return false; // no conversion;
  }
  // Look at trailing text
  while (isspace((unsigned char ) *endptr))
    endptr++;
  return *endptr == '\0';
}

void is_float_test(const char *s) {
  float x;
  printf("Test(\"%s\"):\n", s ? s : "NULL");
  if (is_float(s, &x)) {
    printf("Good (float) %e\n", x);
  } else {
    puts("Bad (float)");
  }
}

int main(void) {
  // Test cases
  is_float_test("123");
  is_float_test(" 123");
  is_float_test("123.456\n");
  is_float_test("123  ");
  is_float_test("123e123");
  is_float_test("123e456");
  is_float_test("  123 xyz");
  is_float_test("  abc");
  is_float_test(" ");
  is_float_test("");

  // Chance for user input
  char buffer[80];
  is_float_test(fgets(buffer, sizeof buffer, stdin));
  return 0;
}

Output

Test("123"):
Good (float) 1.230000e+02
Test(" 123"):
Good (float) 1.230000e+02
Test("123.456
"):
Good (float) 1.234560e+02
Test("123  "):
Good (float) 1.230000e+02
Test("123e123"):
Good (float) inf
Test("123e456"):
Good (float) inf
Test("  123 xyz"):
Bad (float)
Test("  abc"):
Bad (float)
Test(" "):
Bad (float)
Test(""):
Bad (float)

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.