Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Validating digits and/or alpha characters

Posted on 2006-05-28
24
Medium Priority
?
583 Views
Last Modified: 2008-03-04
Hey xperts...

A friend of mine it taking an intro to C class and was asking for my help on a simple program.  But since I don't know anything about "C", it was frustrating trying to help so I figured I'd throw the program out here to you.  She has been given the simple task of writing a program that calculates sales tax and adds it to an inputted purchase amount and it displays the result.  The problem she is having is that she needs to compensate for people entering in a non-digit, like an "a" or something.  I think shes on the right track, but to me the "if" statements look wrong and I think it's giving here the problem.  What happens is, if she enters a non-digit for the purchaseamount, the prgram calculatesa zero amount and displays a zero amount - she wants it to give an error message.  Can you please take a look at the code below and see if ou can give me an answer?  Feel free to change those "if" statements or anything else.... thanks.

----------------------------------------------
----------------------------------------------
#include <stdio.h> //standard input output library
#include <math.h> //math library
#include <system.h> //system library
#include <ctype.h> //character handling library

main()

{ //begin main

      char iSelection='\0'; //Selection of character: number or letter
      float fPurchaseAmount; //Purchase amount
      float fTaxRate=0.00; //Tax rate
      float fTaxAmountDue=0.00; //Amount of Tax Due
      float fGrandTotal=0.00; //Grand Total


      printf("\nWelcome to Kudler Store Tax Calculator\n");
      printf("\n\tKudler Stores\n");
      printf("\n\t-------------\n");
      printf("\n1\tDel Mar\n");
      printf("\n2\tEncinitas\n");
      printf("\n3\tLa Jolla\n\n");
      printf("\nPlease select a store location: ");

      scanf("%d",&iSelection); //Look for selection number entered

fTaxRate=(iSelection-'0'); //conversion

if (iSelection<=3&&iSelection>=1) //if store selection is less than or equal to 3 AND greater than or equal to 1
goto taxSection; //skip down to the tax section
      //end if
      
if (iSelection>3||iSelection<1) //if store selection is greater than 3 OR less than 1, print invalid
printf("\nYour selection is invalid, the program will now terminate.\n");
goto end; //go to the end
      //end if

if (isdigit(iSelection)==0) //if keystroke entered is FALSE, not a digit, print invalid
printf("\nYour selection is invalid, the program will now terminate.\n");
goto end; //go to the end
      //end if

taxSection: //Tax section
if (iSelection==1)
      printf("\n\tYour tax rate is 7.25%%\n\n");
      //end if

if (iSelection==1)
      fTaxRate=0.0725; //if selection equals 1, then the tax rate is 0.0725
      //end if

if (iSelection==2)
      printf("\n\tYour tax rate is 7.5%%\n\n");
      //end if

if (iSelection==2)
      fTaxRate=0.075; //if selection equals 2, then the tax rate is 0.075
      //end if

if (iSelection==3)
      printf("\n\tYour tax rate is 7.75%%\n\n");
      //end if

if (iSelection==3)
      fTaxRate=0.0775; //if selection equals 3, then the tax rate is 0.0775
      goto here; //now goto here section
      //end if

here: //Here section
printf("\nPlease enter purchase amount: $ ");
      scanf("%f",&fPurchaseAmount); //Look for purchase amound entered

if (fPurchaseAmount<0.00);
else goto calculation;
//end if

if (isalpha(fPurchaseAmount)==0); //if store Purchase Amount is less zero print invalid and terminate
printf("\n\tYour input amount is an INVALID keystroke or NEGATIVE amount.\n\tThe program will now terminate.\n");
goto end; //go to the end
//else goto calculation;
//end if
      //end if

//CANNOT GET ALPHA ENTRY TO WORK RIGHT. NUMBER AND NEGATIVE NUMBER WORK CORRECTLY.

if (fPurchaseAmount>0.00); //if store Purchase Amount is greater than zero continue to calculate
goto calculation;
      //end if

//Calculation Section//
calculation:
fTaxAmountDue=(fTaxRate)*(fPurchaseAmount); //Tax amount due is tax rate multiplied by purchase amount
      printf("\n\tYour tax due is: $%.2f\n",fTaxAmountDue);

fGrandTotal=(fTaxAmountDue)+(fPurchaseAmount); //Grand total is tax amount due plus the purchase amount
      printf("\n\tYour grand total bill is: $%.2f\n",fGrandTotal);

end:

} //End main
0
Comment
Question by:edh-home
  • 12
  • 6
  • 5
  • +1
24 Comments
 
LVL 8

Expert Comment

by:Knut Hunstad
ID: 16779291
isalpha returns true when the character is alphabetic. Change to:

if (isalpha(fPurchaseAmount));
0
 
LVL 8

Expert Comment

by:Knut Hunstad
ID: 16779316
While I'm at it, I'll give a few more tips:

1. Get rid of the goto's! Instead of "goto end;", use "return;". Instead of "goto taxSection;", put this into a function or just reorder the code.
2. Instead of:

if (iSelection==2)
     printf("\n\tYour tax rate is 7.5%%\n\n");
     //end if

if (iSelection==2)
     fTaxRate=0.075; //if selection equals 2, then the tax rate is 0.075
     //end if

use:

if (iSelection==2) {
     printf("\n\tYour tax rate is 7.5%%\n\n");
     fTaxRate=0.075; //if selection equals 2, then the tax rate is 0.075
}

3. This is a matter of taste of course, but I would say this is overcommented! When you have used as good variable names as here, then:

fGrandTotal = fTaxAmountDue + fPurchaseAmount;

already tells what happens, the comment "//Grand total is tax amount due plus the purchase amount" actually clutters the code more than clarifies it! In my opinion, that is :-) Same goes for:

    goto here; //now goto here section
 
Just remove the comment, the code is quite clear about what you are doing!

BTW, I just noticed I was sloppy in my first comment, the isalpha-part should be:

if (isalpha(fPurchaseAmount) {
   printf("\n\tYour input amount is an INVALID keystroke or NEGATIVE amount.\n\tThe program will now terminate.\n");
   goto end; //go to the end
}

since writing:

if (something);

will never get anything done, since the ; creates an empty statement. It's either:

if (something)
   DoThis(); // When only one statement is needed

or

if (something) {
   DoThis();
   DoThat();
}

I hope this get's you on the way towards a better program. Good luck!
0
 
LVL 46

Accepted Solution

by:
Kent Olsen earned 1600 total points
ID: 16779323
Hi edh-home,

A couple of things here.

Regardless of the underlying compiler, what is written here is not C.  It's a conversion of BASIC, FORTRAN, COBOL, or some other fairly obsolete language.  For a program of this simplicity, there is absolutely no need to us GOTO.  (And no good excuse for doing same.)

Also, you cannot use isalpha() or isnumeric() on binary data.  These function return true/false based on whether the value is an ASCII character so you must pass a character, not a number.



There are a number of places that can use improvement.  Since this is obviously a homework assignment the rules of the board usually limit the kinds of responses that we can give.  But since this is second hand, the rules can be bent a bit.  I'm going to show you a much better version of the program to allow you to help your friend.  Please understand that the program in its entirety should not be handed back to the student to turn in, but should be used as a learning aid.


#include <stdio.h> //standard input output library
#include <math.h> //math library
#include <system.h> //system library
#include <ctype.h> //character handling library

main()

{ //begin main

     char iSelection='\0'; //Selection of character: number or letter
     float fPurchaseAmount; //Purchase amount
     float fTaxRate=0.00; //Tax rate
     float fTaxAmountDue=0.00; //Amount of Tax Due
     float fGrandTotal=0.00; //Grand Total


  while (1)           /*  Loop continuously until a valid selection is made  */
  {
     printf("\nWelcome to Kudler Store Tax Calculator\n");
     printf("\n\tKudler Stores\n");
     printf("\n\t-------------\n");
     printf("\n1\tDel Mar\n");
     printf("\n2\tEncinitas\n");
     printf("\n3\tLa Jolla\n");
     printf("\n0\t(exit)\n\n");    /*  Allow a way to break out of the loop  */
     printf("\nPlease select a store location: ");

     fflush (stdin);                     /*  Delete any buffered input  */
     fscanf(stdin, "%c",&iSelection); //Look for selection number entered
                                              /*  Use fflush() instead of flush()  */
                                              /*  Read a character instead of an integer  */
     fTaxRate=(iSelection-'0'); //conversion

     switch (iSelection)             /*  Evaluate the input character  */
     {
       case '1':
         printf("\n\tYour tax rate is 7.25%%\n\n");
         fTaxRate=0.0725; //if selection equals 1, then the tax rate is 0.0725
         break;

       case '2':
         printf("\n\tYour tax rate is 7.5%%\n\n");
         fTaxRate=0.075; //if selection equals 2, then the tax rate is 0.075
         break;

       case '3':
         printf("\n\tYour tax rate is 7.75%%\n\n");
         fTaxRate=0.0775; //if selection equals 3, then the tax rate is 0.0775
         break;

       case '0':
         iSelection = 0:  /*  Exit the program  */
         break;

       default:              /*  Handle all illegal characters  */
         printf("\nYour selection is invalid, pleast try again\n");
         fTaxRate = 0;
    }
    if (iSelect == 0)    /*  Exit program  */
      break;

    if (fTaxRate == 0)
    {
      printf ("The selection is not valid.  Please try again.\n\n");
      continue;
    }

    printf("\nPlease enter purchase amount: $ ");
    fflush (stdin);                               /* Clear the input buffer  */
    fscanf("%f",&fPurchaseAmount); //Look for purchase amound entered

    if (fPurchaseAmount < 0)
    {
      printf ("The purchase amount can not be less than $0.00\n");
      continue;
    }
    if (fPurchaseAmount == 0)
    {
      printf ("No purchase was made.\n");
      continue;
    }
    fTaxAmountDue=(fTaxRate)*(fPurchaseAmoun<wbr/>t); //Tax amount due is tax rate multiplied by purchase amount
    printf("\n\tYour tax due is: $%.2f\n",fTaxAmountDue);

    fGrandTotal=(fTaxAmountDue)+(fPurchaseAm<wbr/>ount); //Grand total is tax amount due plus the purchase amount
    printf("\n\tYour grand total bill is: $%.2f\n",fGrandTotal);

  }
} //End main

Good Luck!
Kent
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:edh-home
ID: 16779325
Yea I know about the messy code and incorrect if statements... I hate it too.  But I let her go on her way and learn it.  As far as the comments, she is required to comment on everything in the program by the instructer of the course (sucks, I agree with you).

I will give your suggestions a try.
0
 
LVL 8

Expert Comment

by:Knut Hunstad
ID: 16779344
Oops, bad one! There where so many things there that I missed a major point of the question, that isalpha was testing fPurchaseAmount and not iSelection! Good that Kdo was more alert :-) My point about using:

if (isalpha(WhatEver))

and not

if (isalpha(WhatEver) == 0)

is still correct.

I think my opinion about the course instructors view on code commenting is already clear :-)
0
 

Author Comment

by:edh-home
ID: 16779353
Kent... let me give yours a try too.  ( I dont plan on giving her the answer, I just want to see it work and give her suggestions)... I didnt agree with isalpha or any of that either, but since I really dont know anything about what she's doing, I let her be.

Thanks, I'll report back soon
0
 

Author Comment

by:edh-home
ID: 16779373
Kent,
I am getting the following compile error on your code...
---
c:\edh_prog.c: line 62: unrecognised types in comparison
'if (fTaxRate == 0) { printf ("The selection is not valid.  Please try again.\n\n")'
aborting compile
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16779398
Hi edh-home,

Wow.  It looks like a really bad compiler.

Try:  if (fTaxRate == 0.00)


And as far as the original program goes, if she'll change the type of iSelection to a char, and then use the format of "%c" in the scanf() or fscanf() she can use isdigit().

She'll need the fflush regarless so I suggest that she use fscanf().


Kent
0
 

Author Comment

by:edh-home
ID: 16779419
Kent

Changing it to 0.00 works.  But I run the program and I get the store list, if I choose 0 it exits like it should, but no matter what other input I give it, the program gives a zero result and loops back to the menu:

---here is what I get-----
Welcome to Kudler Store Tax Calculator

        Kudler Stores
        -------------
1       Del Mar
2       Encinitas
3       La Jolla
0       (exit)

Please select a store location: 1

        Your tax rate is 7.25%

Please enter purchase amount: $
        Your tax due is: $0.00

        Your grand total bill is: $0.00

---then the menu again....
0
 
LVL 8

Expert Comment

by:Knut Hunstad
ID: 16779442
To read from stdin, use

scanf("%f",&fPurchaseAmount); //Look for purchase amound entered

or

fscanf(stdin, "%f",&fPurchaseAmount); //Look for purchase amound entered

0
 

Author Comment

by:edh-home
ID: 16779455
the program isn't even getting to the purchaseamount portion
0
 

Author Comment

by:edh-home
ID: 16779469
Kent,

disregard my last comment... i screwed it up by accident.  this works now just how it should.

now, is there a way to do this without having it loop?
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16779486
Hi edh-home,

Sure.  Take out the while(1) statement and the matching '}' near the end of the program.

You'll also have to change some of the print statements (like the ones that say "try again") and the lines that say continue or break will have to be changed to exit or return.


Kent
0
 

Author Comment

by:edh-home
ID: 16779586
Kent,

It works now.  I asked about the loop because she was asked to have the program just end on the error, and I know she will complain to me if I suggest a loop (cuz she already did before, lol).  Now, I have one more question... at the point in the program where you are inputing the purchase amount, how can I compensate for a 'letter'?
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16779610
Hi edh-home,

Compensate?  If you you mean input a letter instead of an integer, use this:

  char cSelection;

  fscanf (stdin, "%c", &cSelection);


The other choice is to keep the current scanf() format and test the return value.  scanf and fscanf return the number of values decoded.

  if (fscanf (stdin, "%d", &iSelection) == 0)   /*  No value was stored so the entered value must be illegal  */
    // print error message and exit.


Kent
0
 

Author Comment

by:edh-home
ID: 16779745
what i mean is if a letter is entered into the purchase amount, she wants the program to give an error and quit.
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16779813
Hi edh-home,

That's exactly what the last snippet will do.

fscanf() and scanf() return the number of items that it successfully decoded.  If you enter a character when scanf() expects a digit, such as when you want a number returned, scanf will NOT store a value and if the format string allows the decoding of several values, decoding stops.  scanf then returns a count that is the number of items decoded and stored.

With a trivial format string ("%d") scanf will return either 0 or 1.  If it returns 1, that means the scanf did not detect a legal value to decode as an integer.  A period, digit, space, dollar sign, etc. was found so decoding wasn't possible.  If scanf returns a 1, that means that it found value input and stored the converted value into iSelection.


Kent
0
 
LVL 85

Expert Comment

by:ozo
ID: 16779815
check the character following
double  strtod(const char * restrict nptr, char ** restrict endptr);
0
 

Author Comment

by:edh-home
ID: 16779882
Well everything works except when I enter a number into the purchase amount... i have to do it twice.
The program gives me the store list, and I enter a number to choose and continue.
I enter '1' and I get my TaxRate.
Then the program asks me to enter a purchase amount.
I enter 100 and press enter.
I actaully have to type 100 again and press enter to get the program to give me a result.
If I enter a letter in the senario, the program ends like it should.
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 16779892
Hi edh-home,

I'm betting that you don't have an fflush () before the second scanf().

  fflush (stdin);
  scanf (.....


Kent
0
 

Author Comment

by:edh-home
ID: 16779906
No I didn't, but after putting that in, I still have to enter the amount twice no matter if I use a digit or a letter.
0
 

Author Comment

by:edh-home
ID: 16781608
Kent

I was playing with this more and it works except for getting to the end of the program where the user inputs a purchase amount (fPurchaseAmount).  The user should enter any number above 0... I can enter a number, such as 100, but when I press enter.. it makes me input the number again without prompting me for it.  If I enter a letter instead of a number, it quits like it should.  Can you please take a look at what I have here and tell me what is wrong?  I thought I had it excactly like you said...  thanks.
-------------------------------
#include <stdio.h> //standard input output library
#include <math.h> //math library
#include <system.h> //system library
#include <ctype.h> //character handling library

main()

{ //begin main

     char iSelection='\0'; //Selection of character: number or letter
     float fPurchaseAmount; //Purchase amount
     float fTaxRate=0.00; //Tax rate
     float fTaxAmountDue=0.00; //Amount of Tax Due
     float fGrandTotal=0.00; //Grand Total


  while (1)           /*  Loop continuously until a valid selection is made  */
  {
     printf("\nWelcome to Kudler Store Tax Calculator\n");
     printf("\n\tKudler Stores\n");
     printf("\n\t-------------\n");
     printf("\n1\tDel Mar\n");
     printf("\n2\tEncinitas\n");
     printf("\n3\tLa Jolla\n");
     printf("\n0\t(exit)\n\n");    /*  Allow a way to break out of the loop  */
     printf("\nPlease select a store location: ");

     fflush (stdin);                     /*  Delete any buffered input  */
     fscanf(stdin, "%c",&iSelection); //Look for selection number entered
                                              /*  Use fflush() instead of flush()  */
                                              /*  Read a character instead of an integer  */
     fTaxRate=(iSelection-'0'); //conversion

     switch (iSelection)             /*  Evaluate the input character  */
     {
       case '1':
         printf("\n\tYour tax rate is 7.25%%\n\n");
         fTaxRate=0.0725; //if selection equals 1, then the tax rate is 0.0725
         break;

       case '2':
         printf("\n\tYour tax rate is 7.5%%\n\n");
         fTaxRate=0.075; //if selection equals 2, then the tax rate is 0.075
         break;

       case '3':
         printf("\n\tYour tax rate is 7.75%%\n\n");
         fTaxRate=0.0775; //if selection equals 3, then the tax rate is 0.0775
         break;

       case '0':
         iSelection = 0;  /*  Exit the program  */
         break;

       default:              /*  Handle all illegal characters  */
         printf("\nYour selection is invalid, pleast try again\n");
         fTaxRate = 0.00;
         continue;
    }
    if (iSelection == 0)    /*  Exit program  */
      break;

    printf("\nPlease enter purchase amount: $ ");
    fflush (stdin);                               /* Clear the input buffer  */
    fscanf(stdin, "%f",&fPurchaseAmount); //Look for purchase amound entered
   
    if (fscanf (stdin, "%f", &fPurchaseAmount) == 0)   /*  No value was stored so the entered value must be illegal  */
    {
      printf ("\nYou entered an INVALID character.");
      break;    // print error message and exit.
    }
   
    if (fPurchaseAmount < 0.00)
    {
      printf ("The purchase amount can not be less than $0.00\n");
      continue;
    }
    if (fPurchaseAmount == 0.00)
    {
      printf ("No purchase was made.\n");
      continue;
    }
    fTaxAmountDue=(fTaxRate)*(fPurchaseAmount); //Tax amount due is tax rate multiplied by purchase amount
    printf("\n\tYour tax due is: $%.2f\n",fTaxAmountDue);

    fGrandTotal=(fTaxAmountDue)+(fPurchaseAmount); //Grand total is tax amount due plus the purchase amount
    printf("\n\tYour grand total bill is: $%.2f\n",fGrandTotal);

  }

} //End main
0
 
LVL 8

Assisted Solution

by:Knut Hunstad
Knut Hunstad earned 400 total points
ID: 16782594
The problem is that you are calling fscanf twice:

fscanf(stdin, "%f",&fPurchaseAmount); //Look for purchase amound entered
   
if (fscanf (stdin, "%f", &fPurchaseAmount) == 0)   /*  No value was stored so the entered value must be illegal  */

change this to either only:

if (fscanf (stdin, "%f", &fPurchaseAmount) == 0)   /*  No value was stored so the entered value must be illegal  */

or:

int iScanResult = fscanf(stdin, "%f",&fPurchaseAmount); //Look for purchase amound entered
   
if (iScanResult == 0)   /*  No value was stored so the entered value must be illegal  */

I would recommend learning how to debug. When you step through the code line by line as it executes, these kind of problems (and many others) are quite easy to spot!
0
 

Author Comment

by:edh-home
ID: 16784820
Kent

Thanks for all the help with this.  I've played with it and cleaned some of it up.  We will work with it to learn from it.

khun.. I saw that, but didnt think of it.  thanks
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
Suggested Courses

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question