2013-10-24 82 views
0

我有一個問題,我搜索了大約半天后找不到實際的解決方案。在這個程序中,我必須填寫一系列有關客戶信息的結構。我還必須做其他一些事情,但我無法弄清我的代碼中的這個錯誤。我知道問題是輸入緩衝區在掃描了大量客戶後在緩衝區中有一個換行符或一個換行符。 許多建議已經在線使用:換行結束getchar()循環過早

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; 
    } 
+0

'#define END_OF_STRING'\ 0'' and'#define NEW_LINE'\ n'' ... please *** NO!*** – 2013-10-24 19:48:39

+0

此外,使用'fgets()'而不是無意義的'scanf )',並將行尾的'\ n'字符改爲NUL-終結符(如果有的話)。並且[不要強制轉換'malloc()']的返回值(http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858)。 – 2013-10-24 19:49:48

回答

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') 
    ; 

錯誤處理,這是我方便(對我來說)被遺漏了。 (#)

+0

感謝您的幫助 –