2017-12-24 10 views
-1

연결된 목록 노드를 만드는 프로그램을 작성하고 있습니다. 그 후, 일부 기능 (삽입, 검색, 업데이트 및 인쇄)을 추가합니다. 연결된 목록에는 번호, 이름 및 수량이 포함되어 있습니다.C : fgets 함수가 작동하지 않는 이유는 무엇입니까?

main 함수는 사용자에게 작업 코드를 입력하도록 요청한 다음 함수가 요청한 작업을 호출합니다.

main() 
{ 
     char code; 
     int c; 
     for(;;) 
     { 
      printf("i: insert\ns: search\nu: update\np: print\n"); 
      printf("Enter operation code: "); 
      scanf("%c",&code); 
      while((c=getchar())!= '\n'&& c!=EOF); 
      switch(code) 
       { 
        case 'i': insert(); 
         break; 
        case 's': search(); 
         break; 
        case 'u': update(); 
         break; 
        case 'p': print(); 
         break; 
        case 'q':return 0; 
        default: printf("Illegal code\n"); 
         break; 
       } 
      printf("\n"); 
     } 
} 

모든 기능이 올바르게 작동합니다. 그러나, 삽입 함수에서, 나는 사용자로부터 문자열 입력을 얻기 위해 fgets 문을 사용한다. (NAME_LEN = 25)

void insert() 
{ 
    node *previous,*current,*new_node; 
    new_node = malloc(sizeof(node)); 
    printf("Enter part number: "); 
    scanf("%d",&new_node->number); 
    for(current = inventory,previous=NULL; 
     current != NULL&& new_node->number > current->number; 
     previous = current,current = current -> next); 
    if(current != NULL && new_node ->number == current->number) 
    { 
     printf("Part already exists.\n"); 
     free(new_node); 

     return; 
    } 
    printf("Enter name part: "); 
    fgets(new_node->Name,NAME_LEN+1,stdin); // i use fgets to input string name 
    printf("Enter quantity on hand: "); 
    scanf("%d",&new_node->on_hand); 
    new_node -> next = current; 

    // move to the next node 
    if(previous == NULL) 
    inventory =new_node; 
    else 
    previous->next = new_node; 

} 

불행히도이 코드는 작동하지 않습니다. 프로그램에서 그 내용을 보여줍니다.

i: insert 
s: search 
u: update 
p: print 
Enter operation code: i 
Enter part number: 2 
Enter name part: Enter quantity on hand: 3 

이름 부분을 놓친 것 같습니다.

또한 새 노드를 삽입하면 프로그램에 자동으로 스위치의 기본 사례가 표시됩니다.

i: insert 
s: search 
u: update 
p: print 
Enter operation code: i 
Enter part number: 2 
Enter name part: Enter quantity on hand: 3 

i: insert 
s: search 
u: update 
p: print 
Enter operation code: Illegal code 

무슨 일이 일어날 지 설명해 주시겠습니까?

+1

무엇이 잘못 되었습니까? – coderredoc

+1

scanf 대신 fgets를 사용하면 scanf가 inbuffer에 내용을 남깁니다. –

+1

힌트 : * "왜 (C 라이브러리 함수 이름 삽입) 함수가 작동하지 않습니까?"* 질문을 시작할 때 대개 - 문제. –

답변

4

글쎄 fgets은 이전 입력에서 stdin에 남은 \n을 사용하고 있습니다. 쉬운 방법은 공백이 아닌 입력을 얻을 때까지 더미 getchar()을 사용하거나 fgets을 사용하는 것입니다.

scanf을 입력 한 후에 한 가지를 수행하면 getchar()입니다.

scanf("%c",&code); 
getchar(); 
^^^^ 
Will consume the `\n`. 

i

그런 다음 i 변수 code에 저장되어 입력 입력한다고 가정하면 좀 더 명확한 설명을 제공합니다. 그러나 \n은 어떨까요? fgets()stdin에서 입력을 읽기 시작하면 \n이 멈 춥니 다. getchar()을 사용하면 \n을 소비했습니다. 이제 모든 공백이 아닌 문자는 \n 또는 EOF 또는 buffer이 가득 찰 때까지 fgets에 의해 소비됩니다.

표준 입력을 플러시하는 데 가장 휴대하고 깨끗한 방법은 \n 문자가 틀림없이 정확해야합니다. 그렇지 않으면 다른 charcaters (물론 유효한 입력)를 먹을 것입니다.).

가비지 입력이 있거나 표준 입력을 지울 때마다 사용할 수 있습니다.

또한 실제로 fgets 기능이 작동하는지 여부를 확인하려면 반환 할 내용을 확인해야합니다. NULL을 반환합니까? 그렇지 않다면 그것을 확인하고 이해하려고 노력하십시오. 단순히 인쇄 할 때 출력이 표시되지 않았기 때문에 버퍼가 fgets이 실패한 것을 의미하지는 않습니다.처음


편집

문제는 바로 scanf("%c",&code)fgets이 있음을 언급 기록했다. 여기에 편집에서 scanf("%d",&new_node->number);fgets 이전에 있지만 시나리오를 변경하지 않는다는 것이 확실합니다. 이제 입력 된 번호 (2ENTER)를 입력 한 후 \n이 그대로 있으며 fgets이 소모됩니다. 따라서 위에 더미 getchar()을 배치하거나 위에 표시된 플러시 기법 stdin을 배치해야합니다.

scanf("%d",&new_node->number); 
getchar(); 
^^^^ 
This consumes the stray `\n` 
+0

여기서 'while'루프는 입력 스트림을 지우는 표준적인 방법이지만, 입력 스트림에 최소한 개행 문자가 있어야 예상대로 작동합니다. –

+0

고맙습니다 만, 삽입 기능을 추가하는 것을 잊어 버립니다. 방금 편집했습니다. 또한, 귀하의 조언을 따르고 불법 번호 문제를 해결할 수 있습니다. 그러나 프로그램을 실행하게하려면 삽입 함수 끝에 2 개의 getchar() 함수를 추가해야합니다. 나는 무슨 일이 일어나는 지 이해하지 못한다. 나 한테 설명해 줄 수 있니, pls? –

+0

삽입 함수의'fgets' 함수는 무엇입니까? '\ n'을 사용하기 전에'getchar()'을 써야합니까? –