Reputation: 163
I'm writing this program for class where it creates customers for a bank. I think I've got the basics - I still have some work to do and a couple things to add. Its compiling with no errors, but I have two problems I can't figure out:
I can add a customer, but when the menu comes up a second time, no matter what option I put in, it goes to the default
in the switch
statement.
Even after adding the customer, if I choose to search for it, it always says not found. If you answer, PLEASE explain, as I am trying to learn :) Thanks for any insight & advice!
customer.c
#include <stdio.h>
#include <stdlib.h>
#include "person.h"
// Program Contstants
#define INTEREST .03
#define CHAR_LEN 40
#define MIN_PRINC 1000
#define MAX_PRINC 1000000
#define MIN_TERM 5
#define MAX_TERM 30
// Program Variables
struct person *customer = NULL;
// Function Prototypes
void addCustomer();
struct person *findCustomer(int custID);
void printCustomer();
int main(void) {
char input;
for (;;) {
printf("\n\nChoose From the Options Below:\n");
printf("Type 'N' to Add a New Customer\n");
printf("Type 'P' to Print a Customer's Information\n");
printf("Type 'Q' to Quit the Program\n\n");
scanf("%c", &input);
while (getchar() != '\n');
switch (toupper(input)) {
case 'N':
addCustomer();
break;
case 'P':
printCustomer();
break;
case 'Q':
exit(0);
default:
printf("Invalid Entry. Please Reenter.\n");
break;
}
}
}
void addCustomer() {
struct person *cur, *prev, *new_node;
new_node = malloc(sizeof(struct person));
if (new_node == NULL) {
printf("The Database is Full. You Cannot Add a New Customer.");
return;
}
printf("\nEnter the Customer ID: ");
scanf("%d", &new_node->custID);
for (cur = customer, prev = NULL;
cur != NULL && new_node->custID > cur->custID;
prev = cur, cur = cur->next);
if (cur != NULL && new_node->custID == cur->custID) {
printf("This Customer ID Already Exists\n");
free(new_node);
return;
}
printf("\nEnter Customer's First Name: ");
gets(new_node->fName);
printf("\nEnter Customer's Last Name: ");
gets(new_node->lName);
printf("\nEnter Customer's Street Address: ");
gets(new_node->address);
printf("\nEnter Customer's City: ");
gets(new_node->city);
printf("\nEnter Customer's 2-Digit State: ");
gets(new_node->state);
printf("\nEnter Customer's 5-Digit Zip Code: ");
gets(new_node->zip);
printf("\nEnter Customer's Principal: ");
scanf("%f", &new_node->principal);
printf("\nEnter Customer's Loan Term (In Years): ");
scanf("%d", &new_node->yearlyTerm);
new_node->next = cur;
if (prev == NULL) {
customer = new_node;
} else {
prev->next = new_node;
}
}
struct person *findCustomer(int custID) {
struct person *p;
for (p = customer; p != NULL && custID > p->custID; p = p->next);
if (p != NULL && custID == p->custID) {
return p;
} else {
return NULL;
}
}
void printCustomer() {
int custID;
struct person *p;
printf("Enter Customer ID: ");
scanf("%d", &custID);
p = findCustomer(custID);
if (p != NULL) {
printf("\nCustomer ID:\t\t%d", p->custID);
printf("\nCustomer's Name:\t%s %s", p->fName, p->lName);
printf("\nCustomer's Address:\t%s", p->address);
printf("\n\t\t\t%s, %s %s", p->city, p->state, p->zip);
printf("\nCustomer's Principal:\t$%.2f", p->principal);
printf("\nCustomer's Loan Term:\t%d", p->yearlyTerm);
} else {
printf("The Customer ID Wasn't Found.\n");
}
}
person.h
// Program Constants
#define MAX_CUSTOMERS 10
#define CHAR_LEN 40
struct person {
int custID;
char fName[CHAR_LEN + 1];
char lName[CHAR_LEN + 1];
char address[CHAR_LEN + 1];
char city[CHAR_LEN + 1];
char state[3];
char zip[6];
float principal;
int yearlyTerm; // Loan Term in Years
int monthlyTerm; // Loan Term in Months
float monthlyPayment; // Calculated Monthly Payment
float actualPayment; // Calculated Monthly Payment Total
struct person *next;
};
Upvotes: 1
Views: 43
Reputation: 144715
The second time scanf("%c", &input);
is executed, it reads the \n
that is pending in standard input after the scanf("%d", ...)
that was executed last.
You can fix this by ignoring any white space before the character you want to read by inserting a space character in front of the %c
:
scanf(" %c", &input);
Note that you should test the return value from scanf
to verify that the input was parsed correctly. You definitely should not use gets()
and you should protect scanf("%s", ...)
by specifying the maximum number of characters to read: scanf("%19s", buffer);
if the buffer
has a length of 20
chars.
The getchar()
loop consumes the rest of the input line where the user selected which option to execute, but look at addCustomer()
: the last input operation is scanf("%d", &new_node->yearlyTerm);
. This call to scanf
leaves the remainder of its line in standard input, including the \n
.
The proper way to flush pending input after your calls to scanf()
is this:
void flush_line(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
}
Note the int
type for c
so it can receive all values of unsigned char
and the special value EOF
. char
would not be correct for this, and your while
loop has a problem: you do not test for EOF
, so the program will run an endless loop at end of file. Try typing control-Z (in Windows) or control-D (on Unix), to verify that.
Also note the explicit continue
statement. Your empty loops are correct for the C syntax, but a tad confusing for the reader because the ;
at the end of the for
clause looks like an error. It is recommended to make this empty body more explicit by using {}
or some other syntactic construction. I personally prefer a single obvious continue;
statement.
Upvotes: 4