?
Solved

Error Checking with a Separate Function

Posted on 2006-03-25
14
Medium Priority
?
228 Views
Last Modified: 2010-04-15
Ok, so now I have this program:

#include <stdio.h>
#include <stdio.h>

main()
{

     /* Variables */
     float yen,canada,euro,real,aussie; /* 5 conversion variables - each variable is the US dollar equivalent to 1 foreign currency */
     char currency; /* the currency/money the user defined */

     /* Display the five possible curreny conversions */
     printf("\nCurrency Conversion \n");
     printf("1) Japanese Yen\n");
     printf("2) Canadian Dollar\n");
     printf("3) European Euro\n");
     printf("4) Brazilian Real\n");
     printf("5) Australian Dollar\n");
     printf("Please select a currency conversion to display: ");
     scanf("%c",&currency);
     

     /* User selects which currency to convert. */

     switch (currency)
     {
          case '1':      /* Japanese Yen Selection */
               yen = 0.00848104;
               printf("\n");
               printf("1 Japanese Yen = %f",yen);
               printf(" US Dollar\n");
               break;

          case '2':      /* Canadian Dollar Selection */
               canada = 0.863782;
               printf("\n");
               printf("1 Canadian Dollar = %f",canada);
               printf(" US Dollar\n");
               break;

          case '3':      /* European Euro Selection */
               euro = 1.1882;
               printf("\n");
               printf("1 European Euro = %f",euro);
               printf(" US Dollar\n");
               break;

          case '4':      /* Brazilian Real Selection */
               real = 0.47259;
               printf("\n");
               printf("1 Brazilian Real = %f",real);
               printf(" US Dollar\n");
               break;

          case '5':      /* Australian Dollar Selection */
               aussie = 0.738002;
               printf("\n");
               printf("1 Australian Dollar = %f",aussie);
               printf(" US Dollar\n");
               break;

          default:     /* Default message in the event user does not enter 1 through 5 selection */
               printf("\n");
               printf("Please rerun the program and enter a number between 1 and 5.");
               printf("\nWould you want to continue [Y for Yes, anything else for No]?");
               fflush(stdin);
               currency = getch();

               if(currency == 'y' || currency == 'Y') /*Error checking to continue or end the program */
               {
                    main();
                    return 0;
               }
               else
                    return 0;

     }

     /* Display the results on the screen */
     fflush(stdin);
     printf("\nPress any key to end.");
     getche();
 
 }


Current my program calls the existing main program, which cannot happen. I need a separate function that checks for user input for all situations, like decimals, negatives, letters, characters, etc. What should I do and can you write out the code for me? Thank you.
0
Comment
Question by:byrianr
11 Comments
 

Author Comment

by:byrianr
ID: 16288721
Ok, I am making some changes. I have the program as follows with a function, but when I put in a decimal, it does not run well. HELP!!!! I need to keep this structure, but make it decimal proof.

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int userinfo(int);

#define TRUE 1
#define FALSE 0

int main()
{

     /* Variables */
     float yen,canada,euro,real,aussie; /* 5 conversion variables - each variable is the US dollar equivalent to 1 foreign currency */
     int currency; /* the currency/money the user defined */


   while (currency != 6)
   {
      /*Call Input Validation function*/
      currency = userinfo(currency);
     
     
     switch (currency)
     {
          case 1:      /* Japanese Yen Selection */
               yen = 0.00848104;
               printf("\n");
               printf("1 Japanese Yen = %f",yen);
               printf(" US Dollar\n");
               break;

          case 2:      /* Canadian Dollar Selection */
               canada = 0.863782;
               printf("\n");
               printf("1 Canadian Dollar = %f",canada);
               printf(" US Dollar\n");
               break;

          case 3:      /* European Euro Selection */
               euro = 1.1882;
               printf("\n");
               printf("1 European Euro = %f",euro);
               printf(" US Dollar\n");
               break;

          case 4:      /* Brazilian Real Selection */
               real = 0.47259;
               printf("\n");
               printf("1 Brazilian Real = %f",real);
               printf(" US Dollar\n");
               break;

          case 5:      /* Australian Dollar Selection */
               aussie = 0.738002;
               printf("\n");
               printf("1 Australian Dollar = %f",aussie);
               printf(" US Dollar\n");
               break;
               
          case 6:      /*User exits program*/
                printf("\n");
                printf("Thank You. Have a nice day. Now exiting the program.");
                break;

          default:     /* Default message in the event user does not enter 1 through 5 selection */
               printf("\n");
               printf("Please rerun the program and enter a number between 1 and 5.");
               printf("\nWould you want to continue [Y for Yes, anything else for No]?");
               fflush(stdin);
               currency = getch();

               if(currency == 'y' || currency == 'Y') /*Error checking to continue or end the program */
               {
                    main();
                    return 0;
               }
               else
                    return 0;

     }
}

     /* Display the results on the screen */
     fflush(stdin);
     printf("\nPress any key to end.");
     getche();
 
 }
 
 int userinfo()
{
      char ucurrency [50]= "";
      int i = 0;
      int flag = TRUE;
      int currency = 0;
     

     
     /* Display the five possible curreny conversions */
     printf("\nCurrency Conversion \n");
     printf("1) Japanese Yen\n");
     printf("2) Canadian Dollar\n");
     printf("3) European Euro\n");
     printf("4) Brazilian Real\n");
     printf("5) Australian Dollar\n");
     printf("6) Exit Program\n");
     printf("Please select a currency conversion to display: ");
     gets(ucurrency);
     
      while(1)
      {
         for( i=0; ucurrency[i] != '\0'; i++)
                {
                   if(!isdigit(ucurrency[i]) || ucurrency[i] != '.')
                       flag = FALSE;
                }
         if (flag = FALSE)
            {
               printf("\nYou have entered an invalid input. Please enter a value between 1-5.");
            }
         else if  (flag = TRUE)
            {
               currency = atoi(ucurrency);
            }
         if(flag = TRUE)
                 break;
       }
   return(currency);
}  
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 16289374
1. replace
gets(ucurrency);

with
fgets (ucurreny, 50, stdin);

2.      /* Display the results on the screen */
     fflush(stdin);
this fflush is undefined .. perhaps you meant fflush(stdout);

3. Use strtol() to validate your input. It will save you a lot of sweat

char * temp;
ret_val = strtol (ucurrency, &temp, 10);
If there is no error, then check tha value pointed by temp. If it is \n or \0 or whitespace, your input was correct.

Cheers!
sunnycoder
0
 
LVL 24

Expert Comment

by:fridom
ID: 16289490
Using gets is always a fault
fflush(stdin) invoked undefined behaviour.

Are you forced you use such case statments? Have you considered putting the information in some structur? Have you learned about structures?

Separate the menu section from the section on how much you like to convert.

This currency problem seems to be a real all-time favourite. I suggest you check other messages about it.

Here's a suggestion for  a menu, IIRC I posted this code some months ago also.

enum {BUF_SIZE=128, MAX_CHOICE=2};
struct info {
  double conversion_factor;
  char *currency_symbol;
};


static struct info currencies[MAX_CHOICE] = {{0.853446, "EUR"},
                                             {1.15, "Can-$"}};

static int menu (void){
  char buf[BUF_SIZE];
  int i_rval = 0;
  char *pc = NULL;
  int i;
 
  int result;
  do {
    printf("%s", "Converting from US-$ to other currencies\n\n");
    for (i = 0; i < MAX_CHOICE; ++i){
      printf("%d for converting to %s\n", i, currencies[i].currency_symbol);
    }
    printf("%d for Quit\n", MAX_CHOICE);
    printf("\nPlease choose ");
    i_rval = fflush(stdout);
    pc = fgets(buf, BUF_SIZE, stdin);
    if (NULL == pc) {
      exit(EXIT_FAILURE);
      /* good enough for an example */
    }
    i_rval = sscanf(buf, "%d", &result);
    if (i_rval != 1 || (result < 0 || result > MAX_CHOICE)) {
      i_rval = 0;
      printf("Not a valid choice please retry\n");
    }
  } while ((0 == i_rval) || result < 0 || result > MAX_CHOICE);
  return result;
}

Feel free to improve it.

Regards
Friedrich
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:byrianr
ID: 16289792
This is what I have. And the Decimal, like 3.4 returns the 3rd option, versus saying it is invalid. What should I do?

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int userinfo(int);

#define TRUE 1
#define FALSE 0

int main()
{

     /* Variables */
     float yen,canada,euro,real,aussie; /* 5 conversion variables - each variable is the US dollar equivalent to 1 foreign currency */
     int currency; /* the currency/money the user defined */


   while (currency != 6)
   {
      /*Call Input Validation function*/
      currency = userinfo(currency);
     
     
     switch (currency)
     {
          case 1:      /* Japanese Yen Selection */
               yen = 0.00848104;
               printf("\n");
               printf("1 Japanese Yen = %f",yen);
               printf(" US Dollar\n");
               break;

          case 2:      /* Canadian Dollar Selection */
               canada = 0.863782;
               printf("\n");
               printf("1 Canadian Dollar = %f",canada);
               printf(" US Dollar\n");
               break;

          case 3:      /* European Euro Selection */
               euro = 1.1882;
               printf("\n");
               printf("1 European Euro = %f",euro);
               printf(" US Dollar\n");
               break;

          case 4:      /* Brazilian Real Selection */
               real = 0.47259;
               printf("\n");
               printf("1 Brazilian Real = %f",real);
               printf(" US Dollar\n");
               break;

          case 5:      /* Australian Dollar Selection */
               aussie = 0.738002;
               printf("\n");
               printf("1 Australian Dollar = %f",aussie);
               printf(" US Dollar\n");
               break;
               
          case 6:      /*User exits program*/
                printf("\n");
                printf("Thank You. Have a nice day. Now exiting the program.");
                break;

          default:     /* Default message in the event user does not enter 1 through 5 selection */
               printf("\n");
               printf("Please rerun the program and enter a number between 1 and 5.");
               printf("\nWould you want to continue [Y for Yes, anything else for No]?");
               fflush(stdin);
               currency = getch();

               if(currency == 'y' || currency == 'Y') /*Error checking to continue or end the program */
               {
                    main();
                    return 0;
               }
               else
                    return 0;

     }
}

     /* Display the results on the screen */
     fflush(stdout);
     printf("\nPress any key to end.");
     getche();
 
 }
 
 int userinfo()
{
      char ucurrency [50]= "";
      int i = 0;
      int flag = TRUE;
      int currency = 0;
     

     
     /* Display the five possible curreny conversions */
     printf("\nCurrency Conversion \n");
     printf("1) Japanese Yen\n");
     printf("2) Canadian Dollar\n");
     printf("3) European Euro\n");
     printf("4) Brazilian Real\n");
     printf("5) Australian Dollar\n");
     printf("6) Exit Program\n");
     printf("Please select a currency conversion to display: ");
    // gets(ucurrency);
     fgets (ucurrency, 50, stdin);
     
      while(1)
      {
        for( i=0; ucurrency[i] != '\0'; i++)
                {
                   if(!isdigit(ucurrency[i]) || ucurrency[i] != '.')
                       flag = FALSE;
                }
         if (flag = FALSE)
            {
               printf("\nYou have entered an invalid input. Please enter a value between 1-5.");
            }
         else if  (flag = TRUE)
            {
               currency = atoi(ucurrency);
            }
         if(flag = TRUE)
                 break;
       }
   return(currency);
}  
0
 
LVL 45

Accepted Solution

by:
sunnycoder earned 1000 total points
ID: 16290714
     while(1) //why do you need this loop? The for loop is sufficient to determine if there was an invalid character and requires only one if else to act on this judgement .. what is the purpose of this infinte loop?
      {
          for( i=0; ucurrency[i] != '\0'; i++)
          {
                  if(!isdigit(ucurrency[i]) || ucurrency[i] != '.')
                        flag = FALSE;
           }
           if (flag = FALSE) //comaprison operator is == and not = this is assignment
           {
                  printf("\nYou have entered an invalid input. Please enter a value between 1-5.");
           }
           else if  (flag = TRUE) //comaprison operator is == and not = this is assignment
           {
                currency = atoi(ucurrency);
           }
           if(flag = TRUE) //comaprison operator is == and not = this is assignment. If this was comparison operator, you would be stuck in infinte loop forever in case of incorrect input
                 break;

Idea is

flag = true
retval=0

scan input char by char
        if there was invalid input
              mark flag to false
               break out of loop

if flag == true
       retval = convert input to int
else
       print error

return retval

Cheers!
sunnycoder
0
 

Author Comment

by:byrianr
ID: 16290793
That does not work. When the choice from the menu is entered, the program ends.
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 16290832
show me the code
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 16290974
I just did the modifications I proposed at my end and it worked fine.

A few observations though::

1. userinfo() prototype declaration and definition are different

2. currency is uninitialized when it is first used in while loop for comparison. You should either use do while loop instead of while loop or initialize it to proper value

3. you dont have to recursively call main .. continuing the loop would serve your purpose

4. Your initialization of yen,canada,euro etc is static and can be done outside the loop. You do not have to perform the initializaion in the loop.

5. Heed to compiler warnings ... More often than not, they are indicative of potential problems.

Cheers!
sunnycoder
0
 

Author Comment

by:byrianr
ID: 16291718
Here is my code:

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int userinfo(int);

#define TRUE 1
#define FALSE 0

int main()
{

     /* Variables */
     float yen,canada,euro,real,aussie; /* 5 conversion variables - each variable is the US dollar equivalent to 1 foreign currency */
     int currency; /* the currency/money the user defined */


   while (currency != 6)
   {
      /*Call Input Validation function*/
      currency = userinfo(currency);
     
     
     switch (currency)
     {
          case 1:      /* Japanese Yen Selection */
               yen = 0.00848104;
               printf("\n");
               printf("1 Japanese Yen = %f",yen);
               printf(" US Dollar\n");
               break;

          case 2:      /* Canadian Dollar Selection */
               canada = 0.863782;
               printf("\n");
               printf("1 Canadian Dollar = %f",canada);
               printf(" US Dollar\n");
               break;

          case 3:      /* European Euro Selection */
               euro = 1.1882;
               printf("\n");
               printf("1 European Euro = %f",euro);
               printf(" US Dollar\n");
               break;

          case 4:      /* Brazilian Real Selection */
               real = 0.47259;
               printf("\n");
               printf("1 Brazilian Real = %f",real);
               printf(" US Dollar\n");
               break;

          case 5:      /* Australian Dollar Selection */
               aussie = 0.738002;
               printf("\n");
               printf("1 Australian Dollar = %f",aussie);
               printf(" US Dollar\n");
               break;
               
          case 6:      /*User exits program*/
                printf("\n");
                printf("Thank You. Have a nice day. Now exiting the program.");
                break;

          default:     /* Default message in the event user does not enter 1 through 5 selection */
               printf("\n");
               printf("Please rerun the program and enter a number between 1 and 5.");
               printf("\nWould you want to continue [Y for Yes, anything else for No]?");
               fflush(stdin);
               currency = getch();

               if(currency == 'y' || currency == 'Y') /*Error checking to continue or end the program */
               {
                    main();
                    return 0;
               }
               else
                    return 0;

     }
}

     /* Display the results on the screen */
     fflush(stdout);
     printf("\nPress any key to end.");
     getche();
 
 }
 
 int userinfo()
{
      char ucurrency [50]= "";
      int i = 0;
      int flag = TRUE;
      int currency = 0;
     

     
     /* Display the five possible curreny conversions */
     printf("\nCurrency Conversion \n");
     printf("1) Japanese Yen\n");
     printf("2) Canadian Dollar\n");
     printf("3) European Euro\n");
     printf("4) Brazilian Real\n");
     printf("5) Australian Dollar\n");
     printf("6) Exit Program\n");
     printf("Please select a currency conversion to display: ");
    // gets(ucurrency);
     fgets (ucurrency, 50, stdin);
     
     while(1)
      {
        for( i=0; ucurrency[i] != '\0'; i++)
                {
                   if(!isdigit(ucurrency[i]) || ucurrency[i] != '.')
                       flag = FALSE;
                }
         if (flag = FALSE)
            {
               printf("\nYou have entered an invalid input. Please enter a value between 1-5.");
            }
         else if  (flag = TRUE)
            {
               currency = atoi(ucurrency);
            }
         if(flag = TRUE)
                 break;
       }
   return(currency);
}  

Show me your code with modifications.
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 16291902
You did not make any modifications which I had suggested .. let me copy paste and explain them again for reference

      while(1) ----- >>>> why do you need this loop? The for loop is sufficient to determine if there was an invalid character and requires only one if else to act on this judgement .. what is the purpose of this infinte loop? Remove it !!
      {
          for( i=0; ucurrency[i] != '\0'; i++)
          {
                  if(!isdigit(ucurrency[i]) || ucurrency[i] != '.')
                        flag = FALSE; ------->>> you can break out of the for loop as soon as you set the flag to false
           }
           if (flag = FALSE) //comaprison operator is == and not = .... this is assignment  ... to compare change it to  if (flag == FALSE) .... note the extra =
           {
                  printf("\nYou have entered an invalid input. Please enter a value between 1-5.");
           }
           else if  (flag = TRUE) //comaprison operator is == and not = ... this is assignment same as above
           {
                currency = atoi(ucurrency);
           }
           if(flag = TRUE) //comaprison operator is == and not = this is assignment. If this was comparison operator, you would be stuck in infinte loop forever in case of incorrect input ... this if can be removed
                 break;

Algorithm is ...

flag = true
retval=0

scan input char by char  ....... (the for loop)
        if there was invalid input     .... if (
              mark flag to false              ..... flag =
               break out of loop

if flag == true                              .... if ( flag == true
       retval = convert input to int            ... atoi
else
       print error

return retval

Cheers!
sunnycoder
0
 
LVL 8

Assisted Solution

by:deepu chandran
deepu chandran earned 1000 total points
ID: 16313521
what you did in this program is complicated way.
you can make this code more simple.

i just rewrite ur userinfo function,
 int userinfo()
{
      int ucurrency;
     /* Display the five possible curreny conversions */
     printf("\nCurrency Conversion \n");
     printf("1) Japanese Yen\n");
     printf("2) Canadian Dollar\n");
     printf("3) European Euro\n");
     printf("4) Brazilian Real\n");
     printf("5) Australian Dollar\n");
     printf("6) Exit Program\n");
     printf("Please select a currency conversion to display: ");
     printf(" %d",ucurrency);
     if((ucurrency<1) &&(ucurrency>6))
     {
        return(ucurrency);
      }
     else
     {
      return -1;//  you can add error message here
     }
}  
 i think this wil help u

cheers
deepu
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

621 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