2013-10-24 4 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''과'#define NEW_LINE'\ n "'... *** NO! *** please! *** –

+0

또한 무의미한'scanf() 대신'fgets()'를 사용하십시오.)'로 바꾸고, 줄의 끝에있는'\ n' 문자를 NUL- 종결 자로 바꾼다. 그리고 [malloc()의 반환 값을 캐스팅하지 마십시오.] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858). –

답변

0

이 일반적인 문제, 그리고 해결책은 매우 간단하다 : 항상 전체 라인 당신이 뭔가를 읽을 때마다 읽습니다.

최대 나중에 읽어 엉망, 입력 버퍼에서 줄 바꿈을 두지 마십시오. Do not는 (당신이 지금하고있는 것처럼 보이기 때문에) 거기에 두지 말고 텍스트 줄을 읽을 때 나중에 건너 뛰도록하십시오. 마지막 줄 바꿈을 포함하여 사용자가 입력 한 전체 줄을 항상 사용하십시오.

이 작업을 수행하는 방법을 정확하게에 대한 일반적인 조언 라인을 읽을 비슷한는 fgets 또는 무언가를 사용하고 atoi 함수 또는 sscanf에서 또는 유사한 것을 사용 내용을 처리하는 것입니다. 또 다른 가능성은 getchar를 사용하여 항상 입력 버퍼에 남아있는 개행 문자를 읽고 즉시 버리는 것입니다. 아마도,이

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

또는 :

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

을 하나 이렇게 :

그러니 이렇게 결코 내가 편리하게 가지고 오류 처리와

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

, (나를 위해) 떠났다.

+0

도움 주셔서 감사합니다. –