Direktes Setzen von Strukturelementen
-
Hallo,
es ist gut möglich, dass das Thema bereits behandelt wurde, obwohl ich es nicht gefunden habe (JA, ich habe gesucht ;-)). In diesem Fall reicht mir schon ein Link zu dem entsprechenden Thread, danke!!
Also..nun zur Sache: Ich habe eine Struktur mit vielen Variablen..Beispiel:
struct pers { int id; char type; char *name; int magic; int mu, kl, ch, in , ff, kk, lp, lpmax, ad, admax, mr, so, ap, ag, st; int last; struct pers near *next; };
Dazu habe ich ein config File, aus dem diese Struktur gefüllt werden soll:
name BLAH
type p
mu 13
kl 12
ch 11
in 12
ff 12
kk 12
lp 28
lpmax 28
[...]Ich lese nun jede Zeile einzeln ein und benutze das Leerzeichen als Trenner. Der erste Wert landet in der char* Variablen att, der zweite in val.
Somit ist als Beispiel für die erste Zeile nun att="name" und val="BLAH".
Ich möchte nun den Pointer current auf die o.g. Struktur mit den Daten füttern, d.h. current->name soll "BLAH" werden. Dies möchte ich direkt mit einer Funktion für JEDES Element hinkriegen, falls das möglich ist, also quasi:
current->att = val;
Das funktioniert natürlich so nicht (IO.C(103) : error C2038: 'att' : not struct/union member), andererseits möchte ich auch nicht jedes Element einzeln setzen, weil das einfach so viele sind und immer mehr werden, sondern dies eben aus der Schleife heraus erledigen, die die Datei zeilenweise einliest.
Da fehlt mir bestimmt nur ein Kniff, und falls den jemand von Euch parat hat oder Euch sonst irgendwas dazu einfällt, bitte meldet Euch ;-)!!!
Vielen liebe Dank schonmal und schönen Abend noch,
Gruß
Dominik
-
Ich würd mal sagen, da mußt du wohl in den sauren Apfel beißen ...
-
Wenn ich mich nicht irre,
müsste der aufruf mit structur.att=var auch nen fehler ergeben
-
Jawoll, auch das funktioniert nicht!
Wenn es nicht möglich ist, das so zu lösen wie ich gedacht hatte, muss es doch anders auch eleganter gehen, als jedes einzelne Element manuell zu setzen, oder?? Irgendeine Idee?
Gruß
Dominik
-
wie gesagt ...
Strukturen haben eben den Sinn, dass man die Elemente mit Namen anspricht.
-
Mehrere Elemente des gleichen Typs kannst du natürlich als Array anlegen. Dann ist allerdings kein direktes Ansprechen über den Namen möglich.
-
So geht's, wenn Du die Attribute mit Namen ansprichst.
In Person.h#ifndef PERSON_H #define PERSON_H #ifndef BOOL #define BOOL int #define FALSE 0 #define TRUE (!FALSE) #endif typedef enum _VarTyp { VAR_CHAR = 1, VAR_INT, VAR_STRING } VarTyp; typedef union _VarWert { int i; char c; char* s; } VarWert; typedef struct _Attr { char* szVar; /* Bezeichnung der Variablen / des Attributs */ VarTyp eTyp; /* int, char oder char* */ VarWert uWert; /* Wert des Attributs */ BOOL bValid; /* Flag, ob Attribut gueltig ist */ } Attr; #define MAX_ATTR 100 struct _Person { Attr aAttr[MAX_ATTR]; /* Eine Person hat eine Reihe von Attributen */ int iAnzAttr; struct _Person* next; }; typedef struct _Person Person; Person* Person_New(void); /* Person erzeugen */ void Person_Delete(Person*); /* Person loeschen */ Attr* Person_GetAttr(Person*, const char*); /* Personenattribut ansprechen */ BOOL Person_SetAttr(Person*, const char*, const char*); /* Attribut setzen */
-
Implementierung in Person.c
#include <stdlib.h> #include <string.h> #include "Person.h" static void Person_NewAttr(Person*, const char*, VarTyp); void Person_NewAttr(Person* _pPerson, const char* _szVar, VarTyp _eTyp) { Attr* pAttr = &_pPerson->aAttr[_pPerson->iAnzAttr]; pAttr->szVar = strdup(_szVar); pAttr->eTyp = _eTyp; pAttr->uWert.s = NULL; pAttr->bValid = FALSE; _pPerson->iAnzAttr++; } Attr* Person_GetAttr(Person* _pPerson, const char* _szVar) { int iIndex = 0; Attr* pAttr; while(iIndex < _pPerson->iAnzAttr) { pAttr = &_pPerson->aAttr[iIndex]; if(!stricmp(pAttr->szVar, _szVar)) return pAttr; iIndex++; } return NULL; } BOOL Person_SetAttr(Person* _pPerson, const char* _szVar, const char* _szWert) { Attr* pAttr = Person_GetAttr(_pPerson, _szVar); if(!pAttr) return FALSE; switch(pAttr->eTyp) { case VAR_CHAR: pAttr->uWert.c = *_szWert; break; case VAR_INT: pAttr->uWert.c = atoi(_szWert); break; case VAR_STRING: if(pAttr->bValid) free(pAttr->uWert.s); pAttr->uWert.s = strdup(_szWert); break; default: return FALSE; } pAttr->bValid = TRUE; return TRUE; } Person* Person_New(void) { Person* pPerson = (Person*) malloc(sizeof(Person)); if(pPerson) { pPerson->next = NULL; pPerson->iAnzAttr = 0; Person_NewAttr(pPerson, "id", VAR_INT); Person_NewAttr(pPerson, "type", VAR_CHAR); Person_NewAttr(pPerson, "name", VAR_STRING); Person_NewAttr(pPerson, "magic", VAR_INT); Person_NewAttr(pPerson, "mu", VAR_INT); Person_NewAttr(pPerson, "kl", VAR_INT); Person_NewAttr(pPerson, "ch", VAR_INT); Person_NewAttr(pPerson, "in", VAR_INT); Person_NewAttr(pPerson, "ff", VAR_INT); Person_NewAttr(pPerson, "kk", VAR_INT); Person_NewAttr(pPerson, "lp", VAR_INT); Person_NewAttr(pPerson, "lpmax", VAR_INT); Person_NewAttr(pPerson, "ad", VAR_INT); Person_NewAttr(pPerson, "admax", VAR_INT); Person_NewAttr(pPerson, "mr", VAR_INT); Person_NewAttr(pPerson, "so", VAR_INT); Person_NewAttr(pPerson, "ap", VAR_INT); Person_NewAttr(pPerson, "ag", VAR_INT); Person_NewAttr(pPerson, "st", VAR_INT); Person_NewAttr(pPerson, "last", VAR_INT); } return pPerson; } void Person_Delete(Person* _pPerson) { int iIndex = 0; Attr* pAttr; while(iIndex < _pPerson->iAnzAttr) { pAttr = &_pPerson->aAttr[iIndex]; free(pAttr->szVar); if(pAttr->eTyp == VAR_STRING) free(pAttr->uWert.s); iIndex++; } free(_pPerson); }
-
Ach ja, und es gilt natürlich wie immer "Geht nicht" gibt's nicht
MfG, Krösus
-
grins
ich bin sicher, das ist genau das, was der OP sucht
-
OP???
-
original poster
usenet-slang, sorry