C Struct - Fehlerhafte for-Schleife



  • Hi, ich bins nochmal. Ich hoffe ich spamme nicht, aber ich habe wieder ein problem. Mein Code macht folgende bildschirmausgabe

    Geben Sie bitte den Namen der 1 Person ein: Frank
    Geben Sie bitte die Nummer der 1 Person ein: 12345
    Geben Sie bitte den Namen der 2 Person ein: Geben Sie bitte die Nummer der 2 Per
    son ein:

    Bei folgendem Code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct daten{
           char Name[20];
           int Nummer[20];
           };
    
    int main(int argc, char *argv[])
    {
      int iLoop;
      struct daten Person[2];
    
      for (iLoop=0; iLoop <2; iLoop++){
          printf("Geben Sie bitte den Namen der %d Person ein: ", iLoop+1);
          gets(Person[iLoop].Name);
          printf("Geben Sie bitte die Nummer der %d Person ein: ", iLoop+1);
          scanf("%d", &Person[iLoop].Nummer);
          //            printf("\n\n");
            //          printf("________________________________________________________________________________");
              //        printf("\n\n");
          }
    
      for (iLoop=0; iLoop <2; iLoop++){
          printf("Der Name der %d Person lautet: %s\n", iLoop+1, Person[iLoop].Name);
                      printf("\n\n");
                      printf("________________________________________________________________________________");
                      printf("\n\n");
          printf("Die Telefonnummer der %d Person lautet: %d", iLoop+1, Person[iLoop].Nummer);
          }
    
      system("PAUSE");	
      return 0;
    }
    

    Er überspringt die Zeile wo ich den Namen der 2 Person eingeben möchte.

    Wäre über Hilfe dankbar.


  • Mod

    So ziemlich alles falsch, was man falsch machen kann.

    -gets is dangerous and should not be used. Es ist sogar so gefährlich, dass es ganz offiziell "deprecated" ist, d.h. es kann bei der nächsten C-Revision durchaus rausfliegen.
    -Eine Telefonnummer ist keine Zahl (du liest mit %d eine Zahl).
    -Sie ist auch keine Zahlenfolge (du hast mit Datentyp int[20] eine Zahlenfolge).
    -Sie ist eine Ziffernfolge, besser noch eine Zeichenfolge (weil viele Leute die Telefonnummer mit '+','(',')','/', ' ' und ähnlichem formatieren. In manchen Ländern auch gerne mit Buchstaben drin).
    -gets (und fgets) liest bis zum ersten Zeilenumbruch, inklusive dem Zeilenumbruch. scanf liest bis dahin, wo die vorgegebene Formatierung nicht mehr passt, exklusive dem ersten Zeichen, welches nicht mehr passt. Wenn du eine eingegebene Zahl mit einem Zeilenumbruch abschließt, dann verbleibt der Zeilenumbruch. Ein darauf folgendes gets liest dann folglich nur diesen Zeilenumbruch ein.

    Computer überspringen nicht einfach so etwas. Sie tun genau(!), was du ihnen sagst. Wenn du dir nicht sicher bist, was dein Programm warum tut, dann nutz einen Debugger. Dann würdest du sehen, dass das gets eben nicht "übersprungen" wird, sondern einfach nur eine leere Zeile einliest.
    Schalte auch Compilerwarnungen an. Der Compiler kann durchaus erkennen, dass deine Datentypen bei scanf nicht passen (Lesen einer Zahl in ein Array von Zahlen. Auch wenn hier beides falsch ist) und kann dir das auch sagen. Ebenso beim späteren printf.

    Warum benutzt du eigentlich manchmal ungarische Notation und manchmal nicht? Weil du gemerkt hast, dass es bei komplexen Datentypen oft uneindeutig ist, welches die richtige Abkürzung ist? Falls ja: Dann ist es doch auch bei einfachen Datentypen recht sinnlos :p .



  • SeppJ schrieb:

    So ziemlich alles falsch, was man falsch machen kann.

    -gets is dangerous and should not be used. Es ist sogar so gefährlich, dass es ganz offiziell "deprecated" ist, d.h. es kann bei der nächsten C-Revision durchaus rausfliegen.
    -Eine Telefonnummer ist keine Zahl (du liest mit %d eine Zahl).
    -Sie ist auch keine Zahlenfolge (du hast mit Datentyp int[20] eine Zahlenfolge).
    -Sie ist eine Ziffernfolge, besser noch eine Zeichenfolge (weil viele Leute die Telefonnummer mit '+','(',')','/', ' ' und ähnlichem formatieren. In manchen Ländern auch gerne mit Buchstaben drin).
    -gets (und fgets) liest bis zum ersten Zeilenumbruch, inklusive dem Zeilenumbruch. scanf liest bis dahin, wo die vorgegebene Formatierung nicht mehr passt, exklusive dem ersten Zeichen, welches nicht mehr passt. Wenn du eine eingegebene Zahl mit einem Zeilenumbruch abschließt, dann verbleibt der Zeilenumbruch. Ein darauf folgendes gets liest dann folglich nur diesen Zeilenumbruch ein.

    Computer überspringen nicht einfach so etwas. Sie tun genau(!), was du ihnen sagst. Wenn du dir nicht sicher bist, was dein Programm warum tut, dann nutz einen Debugger. Dann würdest du sehen, dass das gets eben nicht "übersprungen" wird, sondern einfach nur eine leere Zeile einliest.
    Schalte auch Compilerwarnungen an. Der Compiler kann durchaus erkennen, dass deine Datentypen bei scanf nicht passen (Lesen einer Zahl in ein Array von Zahlen. Auch wenn hier beides falsch ist) und kann dir das auch sagen. Ebenso beim späteren printf.

    Warum benutzt du eigentlich manchmal ungarische Notation und manchmal nicht? Weil du gemerkt hast, dass es bei komplexen Datentypen oft uneindeutig ist, welches die richtige Abkürzung ist? Falls ja: Dann ist es doch auch bei einfachen Datentypen recht sinnlos :p .

    Danke dafür, habs jetzt gelöst. Ich glaube es ist einfach zu Spät für mich jetzt klar zu denken.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct daten{
           char Name[20];
           char Nummer[20];
           };
    
    int main(int argc, char *argv[])
    {
      int iLoop;
      struct daten Person[2];
    
      for (iLoop=0; iLoop <2; iLoop++){
          printf("Geben Sie bitte den Namen der %d Person ein: ", iLoop+1);
          scanf("%s",&Person[iLoop].Name);
          printf("Geben Sie bitte die Nummer der %d Person ein: ", iLoop+1);
          scanf("%s", &Person[iLoop].Nummer);
                      printf("\n\n");
                      printf("________________________________________________________________________________");
                      printf("\n\n");
          }
    
      for (iLoop=0; iLoop <2; iLoop++){
          printf("Der Name der %d Person lautet: %s\n", iLoop+1, Person[iLoop].Name);
    
          printf("Die Telefonnummer der %d Person lautet: %s\n", iLoop+1, Person[iLoop].Nummer);
                      printf("\n\n");
                      printf("________________________________________________________________________________");
                      printf("\n\n");
          }  
      getch();
      return 0;
    }
    

    ps: was meinst du mit

    Warum benutzt du eigentlich manchmal ungarische Notation und manchmal nicht? Weil du gemerkt hast, dass es bei komplexen Datentypen oft uneindeutig ist, welches die richtige Abkürzung ist? Falls ja: Dann ist es doch auch bei einfachen Datentypen recht sinnlos :p


  • Mod

    Schöner wäre es aber schon, wenn man Leerzeichen im Namen und Telefonnummer haben dürfte. Und wenn man dein Programm nicht durch falsche Eingaben kapern könnte.

    scanf(" %19[^\n]", Person[iLoop].Name);  // (Der Adressoperator hier ist ebenfalls falsch, auch wenn es trotzdem funktionieren wird)
    

    Ebenso bei der Telefonnummer. Beachte das Leerzeichen am Anfang des Formatstrings, das heißt, es werden alle Whitespaces am Anfang übersprungen. Ist hier zwar nicht zwingend nötig, aber oft schöner. 19 ist hier die maximale Zahl zu lesender Zeichen. [...] gibt Zeichen an, die erlaubt sind. [^...] gibt Zeichen an, die nicht erlaubt sind. Also wird hier gelesen bis maximal 19 Zeichen oder bis das erste nicht-erlaubt Zeichen (Zeilenumbruch '\n') erreicht wird. Siehe:
    http://www.cplusplus.com/reference/cstdio/scanf/

    Bezüglich ungarische Notation: Manchmal machst du ein Kürzel an deine Variablen, was für ein Datentyp sie sind, manchmal nicht.


Log in to reply