I am trying to write a program that takes a series of numbers input by a user and performs some calculations on it. While I have most of the code put together and working perfectly fine, I haven't been able to write code that will refuse the users input if it is a number followed by letters (ie., "12a" or "12f345"). For some reason, this causes the program to close. Below is the snippet of code isolated to test with.

How can I get the code to display a message that the user input was not a number, to ask for a valid number, and to not close the program?

Thank you, All...

#include <stdio.h>


int main(void)
{
    float num1;
    printf("Please enter a number:");
    while(! scanf("%f", &num1))    
              {      
                     printf("\n\tInvalid entry, please try again: ");       
                     fflush(stdin);
    }
    printf("The number you entered was %.2f\n", num1);
    getChar();
}

Edited 3 Years Ago by Dani: Formatting fixed

One way to do this, which is easiest on the user, is to extract the numeric content of the entry and go on. Here is a simple code snippet:

// A foolproof input routine for numbers:
// The input string is analyzed for nondigit characters
// which are removed, the resulting cleaned string is
// then converted to a real number with atof()
// converts entries like -$12.34, 98F or 345.2KG
// coded using free Pelles C

#include <stdio.h>
#include <ctype.h>   // isdigit()
#include <string.h>  // strlen()
#include <stdlib.h>  // atof()

#define  EOS  0      // end of string marker

double real_in(void);

int main()
{
  double db;

  printf("\n(Enter a zero to exit)\n");
  do 
  {
    db = real_in();
    printf("\nNumeric content = %f\n",db);
  } while(db != 0);
  
  return 0;
}


// enter the value as string then process to float
double real_in()
{
  static char  s1[25], s2[25];
  int k, n = 0;

  printf("\nEnter a number  : ");
  gets(s1);
  for (k = 0; k < strlen(s1); k++)
    // retain - and .
    if (isdigit(s1[k]) || s1[k] == '.' || s1[k] == '-') {
      s2[n] = s1[k];
      n++;
    }
  s2[n] = EOS;
  // convert string to float and return
  return (atof(s2));
}

You must be careful when you advertise "foolproof".

  1. Never use gets(). That immediately makes the code foolprone.
  2. There are a few other characters that might be legal in a double ('+', 'e', and 'E' come to mind). The standard functions handle this, whereas this function does not.
  3. I don't know if "cleaning" the string is the best approach. I would think that if invalid characters are found, the user should be re-prompted to enter correct information -- rather than making possibly unwarranted assumptions about user intent.

You must be careful when you advertise "foolproof".

  1. Never use gets(). That immediately makes the code foolprone.
  2. There are a few other characters that might be legal in a double ('+', 'e', and 'E' come to mind). The standard functions handle this, whereas this function does not.
  3. I don't know if "cleaning" the string is the best approach. I would think that if invalid characters are found, the user should be re-prompted to enter correct information -- rather than making possibly unwarranted assumptions about user intent.

If you process gets(), then it is not quite as foolprone.
Foolproof, I admit, depends on the pool of fools. I was looking at a bunch of PhDs rather than lawyers.
Yes, by all means improve this simple code example. The user should be informed in some nice fashion!
Thanks for your always august opinions Dave. I do treasure them.
I hope Narue comes back from her vacation soon!

This question has already been answered. Start a new discussion instead.