第二次尝试

时间:2016-02-21 06:43:56

标签: c switch-statement structure

我正在为课程编写这个程序,为银行创建客户。我想我已经掌握了基础知识 - 我还有一些工作要做,还有几件事需要补充。它的编译没有错误,但我有两个问题我无法弄清楚:

  1. 我可以添加一个客户,但是当菜单第二次出现时,无论我输入什么选项,它都会转到default语句中的switch

  2. 即使添加了客户,如果我选择搜索它,也总是说找不到。如果您回答,请解释,因为我正在努力学习:)感谢您的任何见解和帮助;咨询!

  3. 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;
    };
    

1 个答案:

答案 0 :(得分:4)

第二次执行scanf("%c", &input);时,它会在最后执行的\n之后读取标准输入中待处理的scanf("%d", ...)

您可以通过在%c前面插入空格字符来忽略要读取的字符前的任何空格来解决此问题:

scanf(" %c", &input);

请注意,您应该测试scanf的返回值,以验证输入是否已正确解析。您绝对不应该使用gets(),如果scanf("%s", ...)的长度为scanf("%19s", buffer);,您应该通过指定要读取的最大字符数来保护buffer 20字符。

getchar()循环消耗输入行的其余部分,用户选择执行哪个选项,但查看addCustomer():最后一个输入操作是scanf("%d", &new_node->yearlyTerm);。对scanf的此次调用会将其余部分留在标准输入中,包括\n

调用scanf()刷新待处理输入的正确方法是:

void flush_line(void) {
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;
}

请注意int的{​​{1}}类型,以便它可以接收c 特殊值unsigned char的所有值。 EOF对此不正确,并且您的char循环有问题:您没有测试while,因此程序将在文件末尾运行无限循环。尝试键入control-Z(在Windows中)或control-D(在Unix上),以验证。

另请注意显式EOF语句。您的空循环对于C语法是正确的,但是对于读者来说有点困惑,因为continue子句末尾的;看起来像是一个错误。建议使用for或其他一些句法结构使这个空体更明确。我个人更喜欢一个明显的{}声明。