0

我有一个问题,在搜索了大约半天后我找不到实际的解决方案。在这个程序中,我必须用客户信息填充结构数组。我还必须做一些其他的事情,但我无法在我的代码中找出这个错误。我知道问题是输入缓冲区在扫描客户数量后在缓冲区中有换行符或换行符。许多人已经在网上建议使用:

while((number = getchar()) != '\n' && number != EOF)
/* discard the character */;

这仅适用于输入的名字,然后我从循环中遇到同样的问题,从客户优先级放置新行或换行。需要有一种方法可以让我取出换行符,而不必担心它。我不能使用类似的东西fflush();或任何类似的功能。

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

#define MIN_CUSTOMERS   2          /* Minimum valid menu choice       */
#define MAX_CUSTOMERS   100        /* Maximum valid menu choice       */
#define MAX_NAME_LENGTH 21         /* Maximum last name length        */
#define END_OF_STRING   '\0'       /* End of string character         */
#define NEW_LINE        '\n'       /* New line character              */
#define QUIT            0          /* Program exit value              */
#define DB_ALLOC_ERROR  1          /* Database allocation error       */

/**********************************************************************/
/*                        Program Structures                          */
/**********************************************************************/
/* A company customer record                                          */
struct customer
{
char  customer_name[MAX_NAME_LENGTH];  /* Last name of customer    */
float amount_owed;          /* Dollar amount customer owes         */
int   priority;             /* Priority number of customer        */
};

/**********************************************************************/
/*                         Function Prototypes                        */
/**********************************************************************/

void print_heading();
/* Print  the heading of the program                               */
void print_instructions();
/* Print the program instructions                                  */
int get_number_of_customers();
/* Get the number of customers to be recorded                      */
void get_customers(int quantity,
            struct customer *p_customer_records_start);
/* Ask the user for customers and fills them into the database     */
void clean_names(int quantity,
            struct customer *p_customer_records_start);
/* Clean customer names of everything except letters and spaces    */
void sort_customers(int quantity,
            struct customer *p_customer_records_start);
/* Sort the array of customers alphabetically                      */
void print_customers(int quantity,
                struct customer *p_customer_records_start);
/* Print the items in the customer database                        */

/**********************************************************************/
/*                           Main Function                            */
/**********************************************************************/
int main()
{
int quantity;   /* Amount of customer databases                     */
struct customer *p_customer_records; /* Pointer to the database    */

/* Print the program heading                                       */
   printf("\n\n\n\n\n\n");
   print_heading();

/* Loop through the number of customer database                    */
while(print_instructions(),
            (quantity = get_number_of_customers()) != QUIT)
{

/* Allocate memory for the experimental scientific data values     */
/* and abort if memory is not available                            */
  if((p_customer_records =
      (struct customer*)malloc(sizeof(struct customer) * quantity))
                                                                                 == NULL)
  {
     printf("\nERROR NUMBER %d OCCURRED in main()", DB_ALLOC_ERROR);
     printf("\nCould not allocate memory for experimental data");
     printf("\nThe program is aborting");
     exit(DB_ALLOC_ERROR);
  }

/* Get, clean, sort, and print the database of customers           */
    get_customers(quantity, p_customer_records);
    clean_names(quantity, p_customer_records);
    sort_customers(quantity, p_customer_records);
    print_customers(quantity, p_customer_records);

/* Display end of database processing                               */
    printf("\n\n******* End of Customer Database Processing *******");
    printf("\n");

/* Free the database memory that was allocated                     */
    free(p_customer_records);
}

/* Print goodbye and terminate                                     */
printf("\nThanks for processing accounts. Have a nice day! :-)");
return 0;
}

这是我得到数量的地方。

/**********************************************************************/
/*                      Get number of customers                       */
/**********************************************************************/
int get_number_of_customers()
{
int quantity; /* Quantity of experimental scientific data values   */

   do
   {
    printf("\n\nGet the number of customers for the database");
    printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - -");
    printf("\nHow many customers do you have (2 to 100, 0=quit): ");
            scanf ("%d", &quantity);
   } while (quantity == 1 ||
              quantity < QUIT || quantity > MAX_CUSTOMERS);

return quantity;
}

/**********************************************************************/
/*                     Get customers information                      */
/**********************************************************************/
void get_customers(int quantity,
                                struct customer *p_customer_records_start)
{
struct customer *p_customer; /* Points to each customer            */
char *p_last_name;

/* Loop through the array of customers and get information         */
for(p_customer = p_customer_records_start;
     (p_customer-p_customer_records_start) < quantity; p_customer++)
{

/* Get the customer's last name                                    */
    printf("\n- Customer Information -");
    printf("\n    Enter the customer's last name: ");

    p_last_name = p_customer->customer_name;

这就是我的问题出现的地方。

    do {
        *p_last_name = getchar();
         p_last_name++;
    } while (*(p_last_name - 1) != NEW_LINE);

    *(p_last_name - 1) = END_OF_STRING;

/* Get the amount the customer owes                                */
    printf("    Enter the amount owed: ");
    scanf ("%f", &p_customer->amount_owed);

/* Get the customer's priority                                     */
    printf("    Enter the customer's priority: ");
    scanf("%d", &p_customer->priority);

    while(p_customer->priority < 1 || p_customer->priority > 3)
    {
                printf("    Enter a valid priority (1-3): ");
                scanf ("%d", &p_customer->priority);
    }

如果我在这里使用 while 循环(前面的解释),则优先级永远不会有效并且无限循环开始。

}

return;
    }
4

1 回答 1

0

这是一个常见的问题,解决方案也很简单:每次阅读时都要阅读完整的一行。

永远不要在输入缓冲区中留下换行符,以免弄乱以后的读取。不要(就像您现在正在做的那样)将它们留在那里并稍后在阅读文本行时尝试跳过它们。始终使用用户键入的整行,包括末尾的换行符。

关于如何做到这一点的通常建议是使用 fgets 或类似的东西来读取行,然后使用 atoi 或 sscanf 或类似的东西处理内容。另一种可能性是,当输入缓冲区中还有一个换行符时,总是立即使用 getchar 读取并丢弃换行符。

所以永远不要这样做:

scanf("%d", &p_customer->priority);

要么这样做:

fgets(line, sizeof line, stdin);
sscanf(line, "%d", &p_customer->priority);

或者,可能是这样的:

scanf("%d", &p_customer->priority);
while (getchar() != '\n')
    ;

使用错误处理,我(对我来说)方便地忽略了它。

于 2013-10-24T19:52:39.733 回答