Scanf von struct

German

Well-Known Member
c-b Experte
#22
Wenn ich dir alles vorkaue, lernst du nichts. Also gehen wir mit etwas Logik ran ...

Beispiel:
Die Deklaration der Funktion Dateneingabe oberhalb der main ist
void Dateneingabe(struct Person *const p_individuum);
Der Aufruf der Funktion in der main ist
Dateneingabe(&personen[anzahl]);

Wie könnte dann der Aufruf der Funktion SearchForHometown aussehen, unter den Prämissen
Du übergibst also das Array und die Anzahl Elemente.
und
Aufruf vor die Freigabe des Arrays in der main
?
 
#23
Code:
void Dateneingabe(struct Person *const p_individuum);

void SearchForHometown(const struct Person *const personen, const size_t anzahl);

void Dateneingabe(struct Person *const p_individuum);

void ShowValues(const struct Person *const p_individuum);


int main(void)
{



    
  struct Person *personen = NULL;
  size_t anzahl = 0;

  for (;; ++anzahl)
  {
    printf("Wollen Sie einen Kontakt hinzufuegen?\n");
    printf("Geben sie j fuer ja, n fuer nein ein: ");

    int choice = getchar();
    while (choice != '\n' && getchar() != '\n');
    if (choice != 'j' && choice != 'J')
      break;

    struct Person *tmp = realloc(personen, (anzahl + 1) * sizeof(struct Person));
    if (tmp == NULL)
      break;

    personen = tmp;
    Dateneingabe(&personen[anzahl]);
  }

  for (size_t i = 0; i < anzahl; ++i)
    ShowValues(&personen[i]);

  if (personen != NULL)
    free(personen);

Dateneingabe(&personen[anzahl]);
SearchForHometown(&personen [size_t anzahl]);

Das vor der Main müsste richtig sein, die Ausführung wie bei
Code:
void Dateneingabe(struct Person *const p_individuum);
kriege ich leider nicht hin.
 

German

Well-Known Member
c-b Experte
#24
Reservierter Speicher wird durch die free Funktion freigegeben und ist danach invalid. Wenn ich dir nun zum dritten mal schreibe, dass der Aufruf der SearchForHometown Funktion vor der Freigebe erfolgen muss, meinst du du bekommst es hin die richtige Stelle zu finden? (Was soll eigentlich dieser weitere Aufruf von Dateneingabe?)

Wie viele Parameter wurden für die SearchForHometown Funktion deklariert und wie viele Argumente übergibst du? (Abgesehen davon, dass ich die Parameter auch noch so genannt habe, wie die zugehörigen Variablen in der main, um es wirklich so einfach wie möglich zu machen.)
 
#25
Hab es hinbekommen, danke. Kann es ausführen, aber habe jetzt eine weitere Frage, wenn ich jetzt zB den Ort Berlin abfragen muss, muss ich das dann für jede Stadt tun? Sprich nach dem Motto: if(Ort == "Berlin") ... if (Ort == Stuttgart)... if (Ort == Hamburg) .... ?
 

German

Well-Known Member
c-b Experte
#26
Verstehe deine Frage nicht. Die Funktion fragt nach dem Ort. Wenn du Berlin eingibst wird nach Berlin gesucht und alle Einträge mit Ort Berlin aufgelistet. Wenn du statt dessen Hamburg eingibst, passiert dasselbe mit Hamburg.
 

BAGZZlash

Well-Known Member
#29
Auf Deinem Screenshot wird ja gar nicht der zu suchende Wohnort abgefragt. Außerdem zeigst Du nicht den Code der Funktion, oder bin ich blind? Wie soll man da anfangen zu helfen?
 
#30
Auf Deinem Screenshot wird ja gar nicht der zu suchende Wohnort abgefragt. Außerdem zeigst Du nicht den Code der Funktion, oder bin ich blind? Wie soll man da anfangen zu helfen?

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



struct Person

{
  char Name[32];
  char Vorname[32];
  char Geschlecht[1];
  struct Datum
  {
    unsigned short Tag;
    char Monat[16];
    unsigned int Jahr;
  } Geburtsdatum;
  struct Adresse
  {
    int PLZ;
    int Hausnummer;
    char Strasse[32];
    char Ort[64];
  } Wohnort;
};

void Dateneingabe(struct Person *const p_individuum);

void SearchForHometown(const struct Person *const personen, const size_t anzahl);



void ShowValues(const struct Person *const p_individuum);


int main(void)
{



    
  struct Person *personen = NULL;
  size_t anzahl = 0;

  for (;; ++anzahl)
  {
    printf("Wollen Sie einen Kontakt hinzufuegen?\n");
    printf("Geben sie j fuer ja, n fuer nein ein: ");

    int choice = getchar();
    while (choice != '\n' && getchar() != '\n');
    if (choice != 'j' && choice != 'J')
      break;

    struct Person *tmp = realloc(personen, (anzahl + 1) * sizeof(struct Person));
    if (tmp == NULL)
      break;

    personen = tmp;
    Dateneingabe(&personen[anzahl]);
  }

  for (size_t i = 0; i < anzahl; ++i)
    ShowValues(&personen[i]);

  if (personen != NULL)
    free(personen);
    
    
SearchForHometown(&personen, anzahl);



  return 0;
}

void Dateneingabe(struct Person *const p_individuum)
{
    
  printf("\n\n");
  printf("Neuer Kontakt\n");
  printf("Nachname....................: ");
  scanf("%31s", p_individuum->Name);
  (p_individuum->Name)[31] = 0;
  while (getchar() != '\n');

  printf("Vorname.....................: ");
  scanf("%31s", p_individuum->Vorname);
  (p_individuum->Vorname)[31] = 0;
 
  while (getchar() != '\n');
 
  printf("Geburtstag (im Monat).......: ");
  scanf("%hu", &p_individuum->Geburtsdatum.Tag);
 
  while (getchar() != '\n');
 
      printf("Geburtsmonat................: ");
  scanf("%15s", p_individuum->Geburtsdatum.Monat);
  (p_individuum->Geburtsdatum.Monat)[15] = 0;
 
  while (getchar() != '\n'); 
 
  printf("Geburtsjahr.................: ");
  scanf("%u", &p_individuum->Geburtsdatum.Jahr);
 
  while (getchar() != '\n');


  printf("Strasse.....................: ");
  scanf("%31s", p_individuum->Wohnort.Strasse);
  (p_individuum->Wohnort.Strasse)[31] = 0;
 
  while (getchar() != '\n');

  printf("Hausnummer..................: ");
  scanf("%d", &p_individuum->Wohnort.Hausnummer);
 
  while (getchar() != '\n');
 
  printf("PLZ.........................: ");
  scanf("%d", &p_individuum->Wohnort.PLZ);
 
  while (getchar() != '\n');


  printf("Ort.........................: ");
  scanf("%63s", p_individuum->Wohnort.Ort);
  (p_individuum->Wohnort.Ort)[63] = 0;
  while (getchar() != '\n');
}


void SearchForHometown(const struct Person *const personen, const size_t anzahl)
{
  char buffer[64] = {0};
  printf("\nWollen Sie nach dem Wohnort suchen?: ");
  scanf("%63s", buffer);
  while (getchar() != '\n');

  for (size_t i = 0; i < anzahl; ++i)
    if (strcmp(buffer, personen[i].Wohnort.Ort) == 0)
      ShowValues(&personen[i]);
}


void ShowValues(const struct Person *const p_individuum)
{
  printf("\nKontakt hinzugefuegt:\n");
  printf("Name.................: %s\n", p_individuum->Name);
  printf("Vorname..............: %s\n", p_individuum->Vorname);
  printf("Geburtstag (im Monat): %hu\n", p_individuum->Geburtsdatum.Tag);
  printf("Geburtsmonat.........: %s\n", p_individuum->Geburtsdatum.Monat);
  printf("Geburtsjahr..........: %u\n", p_individuum->Geburtsdatum.Jahr);
  printf("Strasse..............: %s\n", p_individuum->Wohnort.Strasse);
  printf("Hausnummer...........: %d\n", p_individuum->Wohnort.Hausnummer);
  printf("PLZ..................: %d\n", p_individuum->Wohnort.PLZ);
  printf("Ort..................: %s\n", p_individuum->Wohnort.Ort);
 
}
 

BAGZZlash

Well-Known Member
#31
Okay, danke.

Auf die Gefahr hin, zu wiederholen, was German ja schon gesagt hat:

1.) Dein Aufruf passt nicht, da Du mit Adressof-Operator aufrufst. Das müsste eigentlich einen Compilerfehler werfen.
2.) Wenn Du Deinen Datenbestand erst leerst, kannst Du ihn danach nicht mehr durchsuchen. Prüfe bitte nochmal ganz genau, was im Code so im Bereich der Zeilen 64 bis 71 passiert, Schritt für Schritt. Bitte hier posten.

Ich fange mal an:
Zeile 64: for (size_t i = 0; i < anzahl; ++i) - Initiiert eine Schleife, die die Zählvariable i verwendet, beim Wert 0 startet und so lange läuft, wie i kleiner als die Variable "anzahl" ist.
Zeile 65: ShowValues(&personen[i]); - Stellt den zugehörigen Schleifenrumpf dar. Ruft für jedes i (also für jedes Element i aus dem Array "personen", Anm. d. Red. :)) die Funktion "ShowValues" auf (welche dann die hinterlegten Werte für die Member dieses Elementes des Arrays auf den Bildschirm wirft).
usw.

Jetzt Du.
 
#33
Okay, danke.

Auf die Gefahr hin, zu wiederholen, was German ja schon gesagt hat:

1.) Dein Aufruf passt nicht, da Du mit Adressof-Operator aufrufst. Das müsste eigentlich einen Compilerfehler werfen.
2.) Wenn Du Deinen Datenbestand erst leerst, kannst Du ihn danach nicht mehr durchsuchen. Prüfe bitte nochmal ganz genau, was im Code so im Bereich der Zeilen 64 bis 71 passiert, Schritt für Schritt. Bitte hier posten.

Ich fange mal an:
Zeile 64: for (size_t i = 0; i < anzahl; ++i) - Initiiert eine Schleife, die die Zählvariable i verwendet, beim Wert 0 startet und so lange läuft, wie i kleiner als die Variable "anzahl" ist.
Zeile 65: ShowValues(&personen[i]); - Stellt den zugehörigen Schleifenrumpf dar. Ruft für jedes i (also für jedes Element i aus dem Array "personen", Anm. d. Red. :)) die Funktion "ShowValues" auf (welche dann die hinterlegten Werte für die Member dieses Elementes des Arrays auf den Bildschirm wirft).
usw.

Jetzt Du.








Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



struct Person

{
  char Name[32];
  char Vorname[32];
  char Geschlecht[1];
  struct Datum
  {
    unsigned short Tag;
    char Monat[16];
    unsigned int Jahr;
  } Geburtsdatum;
  struct Adresse
  {
    int PLZ;
    int Hausnummer;
    char Strasse[32];
    char Ort[64];
  } Wohnort;
};

void Dateneingabe(struct Person *const p_individuum);

void SearchForHometown(const struct Person *const personen, const size_t anzahl);



void ShowValues(const struct Person *const p_individuum);


int main(void)
{



    
  struct Person *personen = NULL;
  size_t anzahl = 0;

  for (;; ++anzahl)
  {
    printf("Wollen Sie einen Kontakt hinzufuegen?\n");
    printf("Geben sie j fuer ja, n fuer nein ein: ");

    int choice = getchar();
    while (choice != '\n' && getchar() != '\n');
    if (choice != 'j' && choice != 'J')
      break;

    struct Person *tmp = realloc(personen, (anzahl + 1) * sizeof(struct Person));
    if (tmp == NULL)
      break;

    personen = tmp;
    Dateneingabe(&personen[anzahl]);
  }
 
 
 
SearchForHometown(personen, anzahl);


  for (size_t i = 0; i < anzahl; ++i)
    ShowValues(&personen[i]);

  if (personen != NULL)
    free(personen);
    
    




  return 0;
}

void Dateneingabe(struct Person *const p_individuum)
{
    
  printf("\n\n");
  printf("Neuer Kontakt\n");
  printf("Nachname....................: ");
  scanf("%31s", p_individuum->Name);
  (p_individuum->Name)[31] = 0;
  while (getchar() != '\n');

  printf("Vorname.....................: ");
  scanf("%31s", p_individuum->Vorname);
  (p_individuum->Vorname)[31] = 0;
 
  while (getchar() != '\n');
 
  printf("Geburtstag (im Monat).......: ");
  scanf("%hu", &p_individuum->Geburtsdatum.Tag);
 
  while (getchar() != '\n');
 
      printf("Geburtsmonat................: ");
  scanf("%15s", p_individuum->Geburtsdatum.Monat);
  (p_individuum->Geburtsdatum.Monat)[15] = 0;
 
  while (getchar() != '\n'); 
 
  printf("Geburtsjahr.................: ");
  scanf("%u", &p_individuum->Geburtsdatum.Jahr);
 
  while (getchar() != '\n');


  printf("Strasse.....................: ");
  scanf("%31s", p_individuum->Wohnort.Strasse);
  (p_individuum->Wohnort.Strasse)[31] = 0;
 
  while (getchar() != '\n');

  printf("Hausnummer..................: ");
  scanf("%d", &p_individuum->Wohnort.Hausnummer);
 
  while (getchar() != '\n');
 
  printf("PLZ.........................: ");
  scanf("%d", &p_individuum->Wohnort.PLZ);
 
  while (getchar() != '\n');


  printf("Ort.........................: ");
  scanf("%63s", p_individuum->Wohnort.Ort);
  (p_individuum->Wohnort.Ort)[63] = 0;
  while (getchar() != '\n');
}


void SearchForHometown(const struct Person *const personen, const size_t anzahl)
{
  char buffer[64] = {0};
  printf("\nWollen Sie nach dem Wohnort suchen?: ");
  scanf("%63s", buffer);
  while (getchar() != '\n');

  for (size_t i = 0; i < anzahl; ++i)
    if (strcmp(buffer, personen[i].Wohnort.Ort) == 0)
      ShowValues(&personen[i]);
}


void ShowValues(const struct Person *const p_individuum)
{
  printf("\nKontakt hinzugefuegt:\n");
  printf("Name.................: %s\n", p_individuum->Name);
  printf("Vorname..............: %s\n", p_individuum->Vorname);
  printf("Geburtstag (im Monat): %hu\n", p_individuum->Geburtsdatum.Tag);
  printf("Geburtsmonat.........: %s\n", p_individuum->Geburtsdatum.Monat);
  printf("Geburtsjahr..........: %u\n", p_individuum->Geburtsdatum.Jahr);
  printf("Strasse..............: %s\n", p_individuum->Wohnort.Strasse);
  printf("Hausnummer...........: %d\n", p_individuum->Wohnort.Hausnummer);
  printf("PLZ..................: %d\n", p_individuum->Wohnort.PLZ);
  printf("Ort..................: %s\n", p_individuum->Wohnort.Ort);
 
}


Demnach müsste es jetzt funktionieren. Die Anmerkung die Zeilen 64 bis 71 nochmals anzuschauen haben tatsächlich geholfen. (Ich hab wirklich nicht viel Zeit da rein zu investieren (leider), natürlich Zeit ist relativ, man nimmt sich Zeit!) Aber manchmal muss man Dinge eben öfters wiederholen, bis es bei dem Anderen ankommt. Vielen Dank auch an German, trotz seiner langsam ungeduldigen Art!
 

German

Well-Known Member
c-b Experte
#34
trotz seiner langsam ungeduldigen Art
Ich bin generell sehr langmütig. Du kannst hier Threads finden, in denen ich in hundert Posts einen Dialog führe. Deiner eigenen Aussage zufolge möchtest du C lernen, was nicht ohne Aufwand von Zeit geht. Und solange jemand lernen will, bin ich auch bereit meine Freizeit zu investieren um dazu beizutragen. Diese Krankheit nennt sich glaube ich Helfersyndrom. Ich schreibe dann auch mal ein paar Zeilen Code, denn auch aus Beispielen kann man lernen. Natürlich gehe ich aber im Gegenzug davon aus, dass zumindest versucht wird den Code zu verstehen und dass Rückfragen kommen, wenn irgendwas unklar ist. Und ich gehe davon aus, dass eindringliche Hinweise gelesen und umgesetzt werden. Irgendwann im Laufe des Threads bin ich allerdings zu dem Gefühl gekommen, dass du es nur noch darauf angelegt hast, dass dir irgendwer schon den Code schreiben wird und du dir nicht mal mehr die Mühe machen musst auch nur das Simpelste, das Aufrufen einer Funktion, selbst zu implementieren. Wenn ich darauf allergisch reagiere, dann weil mir die Freizeit die ich hinein stecke, zu schade dafür ist. Copy/paste ist übrigens nicht geeignet eine Sprache zu lernen.
 
#35
Da herrscht bei mir gerade völliges Unverständnis. @BAGZZlash hat gerade zum vierten mal wiederholen müssen, was ich schon geschrieben habe.


Und du warst dir auch wirklich sicher auch nur eine einzige Zeile davon verstanden zu haben?
Ich bin generell sehr langmütig. Du kannst hier Threads finden, in denen ich in hundert Posts einen Dialog führe. Deiner eigenen Aussage zufolge möchtest du C lernen, was nicht ohne Aufwand von Zeit geht. Und solange jemand lernen will, bin ich auch bereit meine Freizeit zu investieren um dazu beizutragen. Diese Krankheit nennt sich glaube ich Helfersyndrom. Ich schreibe dann auch mal ein paar Zeilen Code, denn auch aus Beispielen kann man lernen. Natürlich gehe ich aber im Gegenzug davon aus, dass zumindest versucht wird den Code zu verstehen und dass Rückfragen kommen, wenn irgendwas unklar ist. Und ich gehe davon aus, dass eindringliche Hinweise gelesen und umgesetzt werden. Irgendwann im Laufe des Threads bin ich allerdings zu dem Gefühl gekommen, dass du es nur noch darauf angelegt hast, dass dir irgendwer schon den Code schreiben wird und du dir nicht mal mehr die Mühe machen musst auch nur das Simpelste, das Aufrufen einer Funktion, selbst zu implementieren. Wenn ich darauf allergisch reagiere, dann weil mir die Freizeit die ich hinein stecke, zu schade dafür ist. Copy/paste ist übrigens nicht geeignet eine Sprache zu lernen.

Ich kann wirklich verstehen, wieso du zu diesem Gedanken gekommen bist, ich hab meine kleine stichelnde Nebenbemerkung auch nicht böse gemeint. Es ist schön, dass es Menschen gibt, die anderen ihr Wissen weitergeben möchten, eben wie du es tust.
Aber wie gesagt habe ich leider nicht unendlich viel Zeit und an manchen Tagen nimmt das Gehirn mehr auf, an anderen leider weniger.
Im Endeffekt bin ich hier jedem dankbar, der etwas dazu beiträgt, dass man hier etwas lernen und sich weiterbilden kann!
 
Oben