Probleme mit: scanf("%s" &var); gets(var);
-
Hallo,
manchen von euch mag unten beschriebenes Problem trivial vorkommen, ich bitte euch dennoch mir zu helfen.
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Mitarbeiter { char Vorname[30]; char Nachname[30]; char Geschlecht; unsigned int p_no; struct Mitarbeiter *next; }; struct Mitarbeiter *insert(struct Mitarbeiter *list, unsigned int *p_numb, char *gesch, char vorn[], char nach[]) { struct Mitarbeiter *new_node = (struct Mitarbeiter*)malloc(sizeof(struct Mitarbeiter)); if (new_node == NULL) { printf("\nFEHLER! Nicht genuegend Speicher frei!"); return list; } new_node->p_no = *p_numb; new_node->Geschlecht = *gesch; strcpy(new_node->Vorname, vorn); strcpy(new_node->Nachname, nach); new_node->next = list; list = new_node; return list; } int main () { int i, anzahl; struct Mitarbeiter *list = NULL; unsigned int p_numb; char gesch; char vorn[30]; char nach[30]; printf("\nAnzahl der einzugebenden Mitarbeiter: "); scanf("%d", &anzahl); for(i = 0; i < anzahl; i++) { printf("\n%d. Mitarbeiter", i+1); printf("\nVorname: "); //scanf("%s", &vorn); gets(vorn); printf("Nachname: "); //scanf("%s", &nach); gets(nach); printf("Geschlecht: "); scanf("%c", &gesch); printf("Personalnr.: "); scanf("%d", &p_numb); list = insert(list, &p_numb, &gesch, vorn, nach); printf("-------------------------"); } return 0; }
Das Programm soll einfach nur Listen erstellen mit der jeweiligen struct.
Allerdings wird beim Ausführen und beim Angelangen bei der Eingabe, immer der "Vorname" übersprungen und so betrachtet, als wäre er gar nicht da...Hatte die Eingabe der Elemente auch in eine extra Funktion verpackt bzw. in der Funktion "insert" selbst.. gleiches Problem nur unterschiedliche Sprünge.
Vielen Dank schon mal!
-
Mit den Listen kenn ich mich noch nicht wirklich auf, das hab ich noch vor mir (Ja, da werden noch ein paar Fragen auftauchen).
Aber ich würde generell mal fgets zum String einlesen verwenden.
Das Vorname übersprungen wird... Steht da dann gar nicht´s drin? Oder Käse?
Würde vermuten es ist nach der Eingabe vonprintf("\nAnzahl der einzugebenden Mitarbeiter: "); scanf("%d", &anzahl);
noch was im Tastaturpuffer, bzw. im Stream.
-
Sorry, nach der eingabe von
printf("Personalnr.: "); scanf("%d", &p_numb);
Meinte ich??
-
Danke für die schnelle Antwort
hab jetzt fflush(stdin); mit eingebaut:
for(i = 0; i < anzahl; i++) { fflush(stdin); printf("\n%d. Mitarbeiter", i+1); printf("\nVorname: "); //scanf("%s", &vorn); gets(vorn); printf("Nachname: "); //scanf("%s", &nach); gets(nach); printf("Geschlecht: "); scanf("%c", &gesch); printf("Personalnr.: "); scanf("%d", &p_numb); list = insert(list, &p_numb, &gesch, vorn, nach); printf("-------------------------"); }
funktioniert jetzt einwandfrei... wobei mir der Hintergrund noch nicht wirklich klar ist.
fgets() wird doch nur für Streams verwendet, oder lieg ich da falsch?
-
Die Lösung ist denkbar schlecht. fflush(stdin) ist nicht portabel (weißt du überhaupt, was das macht?). gets is dangerous and should not be used. Außerdem ist es in C11 sogar aus dem Standard geflogen!
Benutz lieber etwas wie
scanf(" %157[^\n]", employee->first_name); // 157 = länge deines char-Arrays - 1
Das beseitigt sowohl dein Problem, ist zugleich aber portabel und sicher.
-
Kein
gets()
verwenden! Schreibt über alles Puffer hinweg bei böswilligen/fehlerhaften Eingaben.
Compilerwarnungen einschalten! Z.B. ist %d der conversion specifier für(signed) int
und nicht fürunsigned
.Wenn Du auf
gets()
verzichtest werden auch führende Leerzeichen ignoriert. Ausser bei %c - s.u.for(i = 0; i < anzahl; i++) { printf("\n%d. Mitarbeiter", i+1); printf("\nVorname: "); scanf("%29s", vorn); // beachte die width (30-1=29 wg. "terminating null byte") printf("Nachname: "); scanf("%29s", nach); // kein & vor der Variable sonst habe ich ja einen char** printf("Geschlecht: "); scanf(" %c", &gesch); // beachte das Leerzeichen: führende Whitespaces werden ignoriert printf("Personalnr.: "); scanf("%u", &p_numb); // u wg. unsigned list = insert(list, &p_numb, &gesch, vorn, nach); printf("-------------------------"); }
Und zuguterletzt: was soll denn das Schlüsselwort
typedef
hier?typedef struct Mitarbeiter{ ... };
SeppJ hat einen Teil meiner Antwort vorweggenommen und sogar noch besser gelöst. Ich lass das jetzt trotzdem mal so stehen...
-
Bei Arrays kommt kein Adressoperator vor den Namen
Und ich denke, dass die Funktion insert nicht die Adressen von p_numb und gesch braucht.
-
Danke für die Antworten!
Hab die Methode nun so umgesetzt wie vorgeschlagen.
Der Code funktioniert.Zu dem fflush(stdin); :
Leider hab ich nicht viel Ahnung davon. Ich dachte, dass mir die Funktion den Puffer löscht, der bei mehreren scanf() Funktionen entstehen kann.
Sozusagen "bereinigt"?Zu dem typdef:
typedef struct Mitarbeiter { char Vorname[30]; char Nachname[30]; char Geschlecht; unsigned int p_no; struct Mitarbeiter *next; };
macht natürlich nicht viel Sinn.. liegt aber daran, dass die Thematik noch neu für mich ist und entsprechend verwirrend.