6
\$\begingroup\$

Had to create this for my class, figured I'd get some advice/insight on how I can advance my program while making it more efficient. Also want to help anyone who may come across the same assignment and is in need of direction; with this said, I would have regretted copying anyone work because I learned a lot about C syntax while making this rather simple program.

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>

//clrscr();
//make a for loop to have the user enter the acc num and pin only having 3 chances before the program terminates -- kinda met


int account_number, pin, chk_acc_bal, sav_acc_bal;
char choice = 'y' ;





void validate_acc(){
     int user_acc_try, i = 0;
     int user_has_not_entered_right_acc = 1;
     int retries = 3;
     while(retries > 0 && user_has_not_entered_right_acc == 1){
                   printf("\nPlease enter your account number: ");
                   scanf("%d", &user_acc_try);

                   if(user_acc_try != account_number){
                                   printf("You entered the wrong account number\n");
                                   retries--;
                                   }
                   else{
                   user_has_not_entered_right_acc = 0;
                   }
                   }
     }

void validate_pin(){
     int user_pin_try, i=0;
     int user_has_not_entered_right_pin = 1;
     int retries = 3;
     while(retries > 0 && user_has_not_entered_right_pin == 1){
                   printf("Please enter your pin number: ");
                   scanf("%d", &user_pin_try);

                   if(user_pin_try != pin){
                                   printf("You entered the wrong pin number.\n");
                                   retries--;
                                   }
                   else{
                   user_has_not_entered_right_pin = 0;
                   }
                   }
                   if(retries = 0){
                              printf("You have reached maximum tries.");
                              }
     }

void validate(){
     validate_acc();
     validate_pin();
}




void Deposit_Cash_Chk(){

    int deposit_chk;


    printf("How Much would you like to deposit into your checking account?: \n");
    scanf("%d", &deposit_chk);
    // Taking the user entered data and adding it to account balance.
    //Consider adding a if / else, to make sure no negitive numbers are added
    chk_acc_bal += deposit_chk;
    printf("Your new checking account balance is $%d\n", chk_acc_bal);
    printf("\nWould you like to make another transaction?\n");
    printf("\n(y)es / (n)o ? \n");
    scanf(" %c", &choice);

}

void Deposit_Cash_sav(){
     int deposit_sav;

     printf("How much would you like to deposit in your saving account?: \n");
     scanf("%d", &deposit_sav);
     //Take the data from the user entered and add it to the global saving account
     //Consider adding a if / else, to make sure no negitive numbers are added
     sav_acc_bal += deposit_sav;
     printf("Your saving account balance is now $%d", sav_acc_bal);
     //Have the user enter anything in order to contiune
     printf("\nWould you like to make another transaction?\n");
     printf("\n(y)es / (n)o ? \n");
     scanf(" %c", &choice);;
}

void Withdraw_Cash_Chk(){
     int withdraw_chk;

     printf("How much would you like to withdraw from you checking account?: ");
     scanf("%d", &withdraw_chk);
     //Take the user entered data and save it to the global variable
     //print the global var
     chk_acc_bal -= withdraw_chk;
     printf("Your new checking account balance $%d", chk_acc_bal);
     printf("\nWould you like to make another transaction?\n");
     printf("\n(y)es / (n)o ? \n");
     scanf(" %c", &choice);
}

void Withdraw_Cash_Sav(){
     int withdraw_sav;

     printf("How much would you like to withdrawn from your saving account?: ");
     scanf("%d", &withdraw_sav);
     //Take the user entered data and save it to the global variable
     //print globabl variable
     sav_acc_bal -= withdraw_sav;
     printf("Your new saving account balance $%d", sav_acc_bal);
     //have the user enter anything in order to contiune
     printf("\nWould you like to make another transaction?\n");
     printf("\n(y)es / (n)o ? \n");
     scanf(" %c", &choice);
}
void query_account(){
     char q_answer[50];

     printf("Which account would you like to access?: ");
     scanf("%s", &q_answer);
     // if / else, depending on the answer the program will that account
     if(strcmp(q_answer, "checking") == 0){
                 printf("Your account balance for your checking account is $%d", chk_acc_bal);
                 printf("\nWould you like to make another transaction?\n");
                 printf("\n(y)es / (n)o ? \n");
                 scanf(" %c", &choice);
                 }
     else if(strcmp(q_answer, "saving") == 0){
          printf("Your account balance for your saving account is $%d", sav_acc_bal);
          printf("\nWould you like to make another transaction?\n");
          printf("\n(y)es / (n)o ? \n");
          scanf(" %c", &choice);
          }
     else{
          printf("you may have entered something incorrectly. Try again");
          }
}

void transfer_funds(){
     char transfer[50];
     int transfer_amt;

     printf("Which account which would you like to transfer from?: (c)hecking or (s)aving ");
     scanf("%s", &transfer);
     //The if statement will take the users input and see which account to transfer from and how much to transfer
     if(strcmp(transfer, "c") == 0){
                 printf("How much would you like to transfer from your checking?: ");
                 scanf("%d",&transfer_amt);
                 chk_acc_bal -= transfer_amt;
                 sav_acc_bal += transfer_amt;
                 printf("You have successfully transfered %d from your checking to your saving account", transfer_amt);
                 printf("\nWould you like to make another transaction?\n");
                 printf("\n(y)es / (n)o ? \n");
                 scanf(" %c", &choice);
                 }
     else if(strcmp(transfer, "s") == 0){
          printf("How much would you like to transfer from your saving?: ");
          scanf("%d",&transfer_amt);
          sav_acc_bal -= transfer_amt;
          chk_acc_bal += transfer_amt;
          printf("You have successfully transfered %d from your saving to your checking account", transfer_amt);
          printf("\nWould you like to make another transaction?\n");
          printf("\n(y)es / (n)o ? \n");
          scanf(" %c", &choice);
          }
     else{
          printf("you may have entered something incorrectly. Try again");
          }
}


int main(void){

     srand(time(NULL));
     while (account_number < 11111 || pin < 1111){
     account_number = rand() % 99999;
     pin = rand() % 9999;
     }
     chk_acc_bal = rand() % 99999;
     sav_acc_bal = rand() % 99999;

     int action_num;
     char withdraw_acc[10],checking_acc[10];




     printf("Please write down these numbers!\n Your account number is %d\n Your pin number is %d\n",account_number, pin);
     //see if there is a way to clear the screen -- ehh ill leave it
     while(choice == 'y'){
     printf("\n");
     printf("\nWelcome to Max's ATM\n");
     printf("What can we help you with today?\nType the number corresponding with your action.\n\n 1. Withdraw\n 2. Deposit\n 3. Transfer\n 4. Query Account\n");
     printf("\nEnter your Number here: ");
     scanf("%d", &action_num);


     switch(action_num){
                        case 1:
                             validate();
                             printf("\nWhich account would you like to withdraw from? (c)hecking or (s)aving ");
                             scanf("%s", &withdraw_acc);
                             //strcmp is a function in the string library that comapres the string and the string in the variable itself.
                             if(strcmp(withdraw_acc, "c") == 0){
                                             Withdraw_Cash_Chk();
                                             }
                             else if(strcmp(withdraw_acc, "s") == 0){
                                  Withdraw_Cash_Sav();
                                  }
                             else{
                                  printf("That is not an account name.");
                                  }
                             break;

                        case 2:
                             validate();
                             printf("Which account would you like to deposit to? (c)hecking or (s)aving ");
                             scanf("%s", &checking_acc);
                             if(strcmp(checking_acc, "c") == 0){
                                             Deposit_Cash_Chk();
                                             }
                             else if(strcmp(checking_acc, "s") == 0){
                                  Deposit_Cash_sav();
                                  }
                             else{
                                  printf("the account name you entered is incorrect.");
                                  scanf("%d");
                                  }
                             break;

                        case 3:
                             validate();
                             transfer_funds();break;
                        case 4:
                             validate();
                             query_account();break;    
     }
     }
     return 0;
}
\$\endgroup\$
2
\$\begingroup\$

First I want to say that you have good descriptive variable names. You have moved functionality into functions as well, that is also good.

Although you should avoid declaring global variables, it is easier to follow a program flow if you declare the variables in main and then pass the relevant variables to the functions it calls. Another major advantage is that you reuse your functions based on the passed parameters.

e.g.

void validate_acc( int account_number );

always make a habit of initializing all variables when you declare them, it is good practice.

when you use runtime functions you should check the return value e.g. scanf returns the number of argument it has successfully parsed based on the format specifier, if it returns 0 you know something went wrong and can do something about it instead of having a potentially uninitialized variable to deal with.

personally i prefer using fgets/sscanf/atoi/atof for input, fgets is simple to use and can not cause stackoverflow if user enters something unexpected.

even though you have split up your functionality into functions you shouldt go one step further and split it further. It may also be useful to create an enum for the account type

e.g.

typedef enum { SavingsAccount, CheckAccount } AccountType;

you could then use this to help remove duplicate code

e.g.

int Withdraw_Cash(AccountType accType)
{
  int withdrew = 0;
  char* accountType[2] = {"savings", "checking"};

  printf("How much would you like to withdraw from your %s account?: ", 
    accountType[accType] );
...
  return witdrew;
}
\$\endgroup\$
2
  • \$\begingroup\$ Wow thanks man, first thank you for the time you spent typing all that out, and next thank your advice ill try to use fgets more and try to make my functions a little less similar however im not sure i follow the logic on enum, could you break down that function a little more. \$\endgroup\$ Mar 18 '15 at 20:43
  • \$\begingroup\$ by using the enum you can use the same function to handle both account types like in the example above Withdraw_Cash could be used to withdraw from both accounts, you could put both of them in an array instead account[2] then the enum would be index account[SavingsAccout] -= amount; \$\endgroup\$
    – AndersK
    Mar 19 '15 at 18:37
5
\$\begingroup\$

Some of the suggestions that I think you might find useful are:

  1. Indentation
  2. Functions are great because you get to reuse the code. I noticed that you have two separate functions to perform validations. Instead, you could simply pass the value to be validated as a parameter.

    An example of such a function that can be reused over and over again would be:

    int main(int argc, char *argv[]){
        int validate_state=0;
        //(1)----------Validating account number
        validate_state=0;
        validate_state=validate(account_number, 3);
        if (validate_state==0) printf("Invalid Account Number");
    
        //(2)----------Validating Pin number
        validate_state=0;
        validate_state=validate(pin_number, 3);
        if (validate_state==0) printf("Invalid Pin Number");
    
        //(n)----------Validating n'th value with k attempts
        validate_state=0;
        validate_state=validate(n_value, k);
        if (validate_state==0) printf("Invalid Some Number");
    }
    
    int validate (int expected_val, int retries){
        int input;
        scanf("%d", &input); // maybe fgets as the prev comment
        while(retries>0){
            if (input==expected_val){
                return 1;
            }else{
                scanf("%d", &input);
                retries --;
            }   
        }
        return 0;
    }
    
\$\endgroup\$
3
\$\begingroup\$

You've got some repeated code. Your deposit and withdraw routines should have the common code factored out and made into a utility routine.

You're not checking for negative numbers, either in what the user inputs, or in the resulting balance. Is this intentional?

You should never use scanf("%s",...) to read in a string. The reason is that the length isn't specified, so the user can easily overflow the input buffer by typing more characters than you allocated. It's safe to use scanf("%c",...) as that only gets a single character, or scanf("%50s",...) to get up to a specific number of characters. Slightly better is to use fgets(...,stdin) because (a) it allows whitespace and (b) you get to specify the size of the buffer, guaranteeing it won't be overrun.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.