2016-04-06 5 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 


typedef struct record 
{ 
    char name[20]; 
    char surname[20]; 
    char telephone[20]; 

}Record; 

typedef struct node 
{ 
    Record data; 
    struct node *next; 
}Node; 

Node *head = NULL; 

void addRecord(Record s) 
{ 
    Node *newNode; 
    Node *n; 

    newNode = (Node*)malloc(sizeof(Node)); 
    newNode->data = s; 
    newNode->next = NULL; 

    if (head == NULL) 
    { 
     // The linked list is empty 
     head = newNode; 
    } 
    else 
    { 
     // Traverse the whole list until we arrive at the last node 
     n = head; 
     while (n->next != NULL) 
     { 
      n = n->next; 
    } 
     n->next = newNode; 
    } 
} 

Record enterRecordDetails() 
{ 
    Record aRecord; 
    int len; 
    int valid = 0; 
    int valid2 = 0; 
    printf("ENTER THE FOLLOWING RECORD DETAILS:\n"); 

    printf(" NAME  : "); 
    gets(aRecord.name); 
    printf(" SURNAME : "); 
    gets(aRecord.surname); 
    do { 
     valid = 0; 
     valid2 = 0; 
     printf(" TELEPHONE NO. (8 digits): "); 
     gets(aRecord.telephone); 
     len = strlen(aRecord.telephone); 
     for (int i = 0; i < len; i++) 
     { 
      if (!isdigit(aRecord.telephone[i])) { 
       printf("You enterred an invalid number\n"); 
       valid = 1; break; 
      } 
     } 
     Node *p = head;   
      while (p != NULL) 
      { 
       Node *next = p->next; 
       for (; next; p = next, next = next->next) { 
        if (strcmp(p->data.telephone, aRecord.telephone) == 0) 
        { 
         valid2 = 1; break; 
        } 
       } 
       if(p = NULL)break; 
      } 

    } while((valid == 1) || (len != 8) || (valid2 == 1)); 
    getchar(); 
    fflush(stdin); 
    return aRecord; 
} 


int main(void) 
{ 
    char menuOption; 

    do 
    { 
     system("cls"); 
     printf("~~~ MAIN MENU ~~~\n"); 
     printf("1. Add Telephone Record\n"); 
     printf("2. Delete Telephone Record\n"); 
     printf("3. Search\n"); 
     printf("4. Display All Records\n"); 
     printf("5. Exit\n\n"); 
     menuOption = getchar(); 
     fflush(stdin); 
     switch (menuOption) 
    { 
    case '1': 
     addRecordToList(); 
     break; 
    case '4': 
     displayList(); 
     break; 
    } 

} while (menuOption != '5'); 

getchar(); 
return 0; 

}C: gets() überspringt den ersten Eingang

Wenn ein Schüler das Hinzufügen der Computer den Benutzer auffordert, den Namen nicht den Namen einzugeben. Warum überspringt das Programm 'Name'? "Name" wird angezeigt, es wird jedoch erwartet, dass der Benutzer stattdessen den Nachnamen schreibt.

+2

Sie nur einen Teil Ihres Programms gebucht hat. Das ist nicht sehr hilfreich, um das Problem zu diagnostizieren. Bitte veröffentlichen Sie ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve). –

+3

Sie sollten 'gets' nicht verwenden: http://stackoverflow.com/questions/1694036/why-is-the-gets-function-so- dangerous-that-it-hould-not-be-used. –

+1

Das Problem ist die Interaktion von 'gets()' mit vorherigem, nicht hochgeladenem Code. – chux

Antwort

1

Erstens, verwenden Sie nicht gets, es ist unsicher. Verwenden Sie stattdessen fgets.

Der Grund, warum der erste Anruf zu gets eine Zeile überspringt, ist, dass ein '\n' im Puffer zu dem Zeitpunkt ist, zu dem Sie einen Anruf an enterRecordDetails() tätigen. Typischerweise ist der '\n' ein Rest von einer früheren Eingabeoperation, zum Beispiel von einem Lesen einer int mit scanf.

Eine Möglichkeit, dieses Problem zu beheben, ist, die Zeichenfolge bis zum Ende beim Lesen der int zu lesen, so dass der fortlaufende Aufruf von fgets die tatsächlichen Daten erhalten würde. Sie können es in Ihrer enterRecordDetails() Funktion tun:

Record enterRecordDetails() 
{ 
    Record aRecord; 
    printf("ENTER THE FOLLOWING RECORD DETAILS:\n"); 
    printf(" NAME  : "); 
    fscanf(stdin, " "); // Skip whitespace, if any 
    fgets(aRecord.name, 20, stdin); 
    printf(" SURNAME : "); 
    fgets(aRecord.surname, 20, stdin); 
} 

Beachten Sie jedoch, dass fgets'\n' im String hält, solange es in dem Puffer passt. Ein besserer Ansatz wäre mit scanf und einen Formatbezeichner geben, der die Länge des Eingangs begrenzt und hält an '\n':

scanf(" %19[^\n]", aRecord.name); 
// ^
+0

'scanf ("% 19 [^ \ n] ", aRecord.surname);' liest nichts in 'aRecord.surname', wenn das erste Zeichen '' \ n'' ist, so dass es nicht initialisiert ist und das fehlerhafte '' \ n "in' stdin'. Dies würde sicherlich als ein vorheriges 'scanf ("% 19 [^ \ n] ", aRecord.name) geschehen;' konsumiert nicht das ''\ n''. Am besten, 'fgets()' zu verwenden. – chux

+0

@chux Mein einziger Vorbehalt zu 'fgets' ist, dass ich' \ n' in meiner Zeichenfolge behalte. Natürlich ist es leicht, diese Saite loszuwerden, aber es ist besser, sie nicht dort zu haben. – dasblinkenlight

+0

Ich stimme nicht zu, ist _easier_ mit 'scanf()' und nicht die '' \ n'' als 'fgets()'. YMMV. – chux

Verwandte Themen