Dynamische Arrays - Pointer
-
Schau mal.
pArrAktPer = (ppperson_t)calloc(AnzDat,sizeof(person_t));
enthält zwei Unschönheiten: In C++ mußt Du casten, wahrscheinlich compilierst Du eine cpp- Datei. Benenne sie so um, daß die Endung .C lautet oder schau sonst zu, wie Du den Compiler dazu bringst, C zu compilieren. Wenn das ohne cast nicht klappt, mußt Du zur Strafe ins C++- Forum
Zweitens ist das sizeof besser am konkreten Objekt festzumachen, besser also:pArrAktPer = calloc(AnzDat,sizeof(Person));
Beides nachzulesen in den ANSI- C- FAQs
Dann schau mal zu Zeile 53/54: Da weist Du bei i == AnzDat die komische Stopmarke zu, aber wohin? Es gibt nur 0 ... AnzDat-1 Elemente (als Index besehen). Das ist schonmal nicht richtig.
Was Du mit den Strings machst, kommt mir auf den ersten Blick etwas seltsam vor, mach' aber erstmal das Offensichtliche klar, dann sehhen wir weiter ...
-
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LENGTH 50 typedef unsigned int ui_t; typedef char nam_t; typedef struct gd_e { ui_t gdTag; ui_t gdMonat; ui_t gdJahr; }gd_t; typedef struct person_e { ui_t identNr; nam_t fNam[MAX_NAME_LENGTH], vNam[MAX_NAME_LENGTH]; gd_t gebDat; }person_t; //########################################### //# 1. helper fn # //########################################### void clearStdIn(){ char buffer[1024]; fgets(buffer,1024,stdin); } void scanfEx(char *str,void *type){ scanf(str,type); clearStdIn(); } void fgetsEx(char *ret,int len,FILE *fp){ fgets(ret,len,fp); ret[strlen(ret)-1]='\0';//remove '\n' } //########################################### //# 2. Datensätze von der Tastatur einlesen # //########################################### person_t **ReadFromKbd (void) { int i = 0; int AnzDat=0; person_t **Person; printf( "Projekt 1 - Crap Beta T.Mueller | noobLolo\n" "*******************************************\n\n" "Eingabe von bis zu 10 Personendatensaetzen " "(Ende: leerer Familienname)\n\n" "Anzahl einzulesender Datensaetze: " ); scanfEx("%2d", &AnzDat); printf("\n"); if(AnzDat < 1) return NULL; //gibt es ein max wenn ja warum? //if(AnzDat > MAXPERANZ) AnzDat = MAXPERANZ; //array Person = calloc(AnzDat+1,sizeof(person_t*)); if(Person==NULL) return NULL; i=AnzDat; //pArrAktPer[i]=NULL; //unser neuer end wert implizit :) while(i--){ //ein datensatz fuer das array Person[i] = calloc(1,sizeof(person_t)); if(Person[i]==NULL) return NULL; } for(i=0;i<AnzDat;i++){ printf("Datensatz %2d\n", i+1); printf("Familienname: "); fgetsEx(Person[i]->fNam,MAX_NAME_LENGTH-1,stdin); printf("Vorname : "); fgetsEx(Person[i]->vNam,MAX_NAME_LENGTH-1,stdin); printf("Geburt Tag : "); scanfEx("%u", &Person[i]->gebDat.gdTag); printf("Geburt Monat: "); scanfEx("%u", &Person[i]->gebDat.gdMonat); printf("Geburt Jahr : "); scanfEx("%u", &Person[i]->gebDat.gdJahr); printf("Personal-Nr.: "); scanfEx("%u", &Person[i]->identNr); } return Person; } //######################################## //# 3. Datensätze im Bildschirm anzeigen # //######################################## void WritePerToCrt(person_t **Person){ int l=0; printf("Folgende Personen wurden abgespeichert: \n\n"); while(Person[l]){ printf("%5.5u %-*s %-*s %2.2u.%2.2u.%4.4u \n", Person[l]->identNr , MAX_NAME_LENGTH+1, Person[l]->fNam , MAX_NAME_LENGTH+1, Person[l]->vNam , Person[l]->gebDat.gdTag , Person[l]->gebDat.gdMonat , Person[l]->gebDat.gdJahr ); l++; } printf("\n\n"); } //######################################### //# 4. Datensätze in datei speichern # //######################################### //######################################### //# 5. Datensätze aus datei lesen # //######################################### //######################################### //# 6. Free-Funktion - Speicher freigeben # //######################################### void FreeDynMem(person_t **Person){ int l=0; while(Person[l]) free(Person[l++]); free(Person); } int main(void){ person_t **Person; Person = ReadFromKbd(); if(Person==NULL) return 1; WritePerToCrt(Person); FreeDynMem(Person); return 0; }
wie immer ist sicher auch das ein bischen buggy
lg lolo
-
pAktPer[i].fNam[0]!= EMPTYTAG_C
sowas ist ungünstig, denn wer weiß schon was es so für namen gibt, stell dir mal vor du denkst dir da nen namen aus den es deiner meinung nach nicht gibt und dann kommt einer daher und gibt das ein...
als ich meinen führerschein gemacht hab hat mein fahrlehrer immer gesagt man muß mit der dummheit der anderen rechnen,
beim programmieren mußt du immer mit der dummheit des users rechnen, der immer das eingibt woran du nicht gedacht hast
pointercrash() schrieb:
Wenn das ohne cast nicht klappt, mußt Du zur Strafe ins C++- Forum
hab mich ja weggeschossen als ich das gelesen hab *rofl*
-
#define EMPTYTAG_C 0
-
x0r schrieb:
#define EMPTYTAG_C 0
noobLolo schrieb:
beim programmieren mußt du immer mit der dummheit des users rechnen, der immer das eingibt woran du nicht gedacht hast
und mit seiner eigenen
-
genau, ist ne vs c++ consolenanwendung. müssen wir in der uni so benutzen, soll ich nen mod anschreiben damit der thread ins c++ verschoben wird?
dachte hier wär das am besten aufgehoben.
Zeile53 ist jetzt
} while (i < AnzDat); strcpy(pAktPer[i+1].fNam, EMPTYTAG_S);
und das sizeof hab ich auch geändert. dachte ich sprech lieber direkt mit person_t die struktur an statt über eine variable. aber ich vermute ich verstehe irgendwas an calloc oder an zeigern nicht. füg ich die ausgabe direkt unter der schleife ein funktioniert alles einwandfrei
dieses indirekte mit zeigern auf zeiger auf strukturen verwirrt mich noch total...
hab das calloc mal in
pArrAktPer =(pperson_t)calloc(AnzDat+1,sizeof(Person));
geändert, +1 weil ja das schlußzeichen noch gesetzt werden soll.
ich bin etwas irritiert was genau jetzt der linke wert darstellt und wie ich damit umgehen soll.die ausgabe-funktion erwartet einen einfachen zeiger auf die strukturen. pArrAktPer ist doch jetzt aber ein zeiger auf einen zeiger im reservierten speicher, der auf die strukturen personen*Anzahl Datensätze zeigt... oder ist das falsch?
in der schleife möchte ich mit
pAktPer[i] = Person;
jeweils ein datensatz/eine struktur hinzufügen, bin mir nicht sicher ob das so 100% richtig ist, aber es geht wie gesagt merkwürdigerweise wenn ich die ausgabe gleich danach mache.
wenn ich aber versuche über
return pAktPer;
den zeiger zu übergeben, stürzt das programm ab. Bei einigen rumprobier-versuchen mit calloc klappte noch das printf("Folgende Personen usw"), aber dann war ab der for auch schluss...
//herrje bin ich langsam...
-
habs mal bischen geändert
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LENGTH 50 typedef unsigned int ui_t; typedef char nam_t; typedef struct gd_e { ui_t gdTag; ui_t gdMonat; ui_t gdJahr; }gd_t; typedef struct person_e { // Etikett: Struktur Person ui_t identNr; nam_t fNam[MAX_NAME_LENGTH], vNam[MAX_NAME_LENGTH]; gd_t gebDat; }person_t; // Typname: Struktur fuer eine Person //########################################### //# 0. helper fn # //########################################### void clearStdIn(){ char buffer[1024]; fgets(buffer,1024,stdin); } void scanfEx(char *str,void *type){ scanf(str,type); clearStdIn(); } void fgetsEx(char *ret,int len,FILE *fp){ fgets(ret,len,fp); ret[strlen(ret)-1]='\0';//remove '\n' } //########################################### //# 2. Datensätze von der Tastatur einlesen # //########################################### person_t *ReadFromKbd (void) { int i = 0; int AnzDat=0; person_t *Person; printf( "Projekt 1 - Crap Beta T.Mueller | noobLolo\n" "*******************************************\n\n" "Eingabe von bis zu 10 Personendatensaetzen " "(Ende: leerer Familienname)\n\n" "Anzahl einzulesender Datensaetze: " ); scanfEx("%2d", &AnzDat); printf("\n"); if(AnzDat < 1) return NULL; //gibt es ein max wenn ja warum? //if(AnzDat > MAXPERANZ) AnzDat = MAXPERANZ; //array Person = calloc(AnzDat+1,sizeof(person_t)); if(Person==NULL) return NULL; for(i=0;i<AnzDat;i++){ printf("Datensatz %2d\n", i+1); printf("Familienname: "); fgetsEx(Person[i].fNam,MAX_NAME_LENGTH-1,stdin); printf("Vorname : "); fgetsEx(Person[i].vNam,MAX_NAME_LENGTH-1,stdin); printf("Geburt Tag : "); scanfEx("%u", &Person[i].gebDat.gdTag); printf("Geburt Monat: "); scanfEx("%u", &Person[i].gebDat.gdMonat); printf("Geburt Jahr : "); scanfEx("%u", &Person[i].gebDat.gdJahr); printf("Personal-Nr.: "); scanfEx("%u", &Person[i].identNr); } return Person; } //######################################## //# 3. Datensätze im Bildschirm anzeigen # //######################################## void WritePerToCrt(person_t *Person){ int l=0; printf("Folgende Personen wurden abgespeichert: \n\n"); while(Person[l].fNam[0]!=0){ printf("%5.5u %-*s %-*s %2.2u.%2.2u.%4.4u \n", Person[l].identNr , MAX_NAME_LENGTH+1, Person[l].fNam , MAX_NAME_LENGTH+1, Person[l].vNam , Person[l].gebDat.gdTag , Person[l].gebDat.gdMonat , Person[l].gebDat.gdJahr ); l++; } printf("\n\n"); } //######################################### //# 4. Datensätze in datei speichern # //######################################### /*void WritePerToFile(pperson_t pAktPer){ printf("Eingabe Dateiname ohne Erweiterung [ret=perlis]: "); gets(buffer); }*/ //######################################### //# 6. Free-Funktion - Speicher freigeben # //######################################### void FreeDynMem(person_t *Person){ free(Person); } int main(void){ person_t *Person; Person = ReadFromKbd(); if(Person==NULL) return 1; WritePerToCrt(Person); FreeDynMem(Person); return 0; }
scheint so als sollte ich mir das mit den arrays nochmal durch den kopf gehen lassen
-
wie immer ist sicher auch das ein bischen buggy
lg lolo[/quote]
wow, respekt&thx!
aber bei beiden calloc (Zeile 66 & 75) selbes problem wie vorher:
Fehler 2 error C2440: '=': 'void *' kann nicht in 'person_t **' konvertiert werden
// schon wieder gelat0rt -.-
//2 ok, mitm cast gehts. riesen danke, du hast mir ech geholfen!
-
noobLolo schrieb:
x0r schrieb:
#define EMPTYTAG_C 0
noobLolo schrieb:
beim programmieren mußt du immer mit der dummheit des users rechnen, der immer das eingibt woran du nicht gedacht hast
und mit seiner eigenen
Was ist an dem define so dumm? Vielleicht benutzt der Prof noch Magnetbänder zur Speicherung der Datensätze.
-
noobLolo schrieb:
und mit seiner eigenen
das bezog sich darauf das mir diese möglichkeit nicht eingefallen ist