2017-03-06 5 views
1

C Anfänger hier, kämpfen, um eine Lösung für diese online zu finden.Iterate durch Strukturelemente des gleichen Typs

Ich baue gerade eine Funktion zur Ausgabe von Strukturdaten, aber vor der Ausgabe prüft, ob Daten vorhanden sind.

Dies ist meine aktuelle Lösung:

if (strcmp(P.strFullName.arcTitle, " ") != 0) 
    printf("%s ", P.strFullName.arcTitle); 

if (strcmp(P.strFullName.arcFirstName, " ") != 0) 
    printf("%s ", P.strFullName.arcFirstName); 

if (strcmp(P.strFullName.arcMiddleName, " ") != 0) 
    printf("%s ", P.strFullName.arcMiddleName); 

if (strcmp(P.strFullName.arcSurname, " ") != 0) 
    printf("%s ", P.strFullName.arcSurname);   
printf("\n"); 

Alle Strukturelemente sind hier Saiten, und ich würde im Idealfall mit der, ob und printf Funktion einer Schleife durch die Taste 2 Linien in die Lage sein mag, einfach zu ändern Welches Strukturelement betrachtet die Schleife bei jedem Inkrement?

Gibt es eine Möglichkeit, dies zu vereinfachen?

+0

Warum nicht ein Array von Strings in der Struktur haben, und einfach eine Schleife verwenden? – Peter

+0

Können Sie bitte die Strukturierung hinzufügen? –

+0

[Dieses Q/A] (http://stackoverflow.com/questions/1784782/is-there-any-way-to-loop-through-a-stru-with-elements-of-different-types-in-in- c) wird hilfreich sein. –

Antwort

2

Sie können eine kleine Funktion schreiben, die die if-Bedingung enthält und auch druckt.

void CheckAndPrint(char *str) 
{ 
    if (strcmp(str, " ") != 0) 
     printf("%s ", str); 
} 

dann im Haupt Code, den Sie es als,

CheckAndPrint(P.strFullName.arcTitle); 
CheckAndPrint(P.strFullName.arcFirstName); 
CheckAndPrint(P.strFullName.arcMiddleName); 
CheckAndPrint(P.strFullName.arcSurname); 

nennen kann, hat den Vorteil, dass vielleicht später, wenn Sie eine weitere Überprüfung vor dem Drucken hinzugefügt werden sollen, muss es in nur geschehen, ein Platz.

0

Wenn Sie wirklich müssen „iterieren“, können Sie den Standard offsetof Makro verwenden, der Offset jedes Mitglieds zu berechnen, und dann der Struktur durch die Adresse zugreifen:

struct full_name { 
    char const *arcTitle; 
    char const *arcFirstName; 
    char const *arcMiddleName; 
    char const *arcSurname; 
}; 

void print_full_name (struct full_name *fname) { 
    size_t offest[] = { 
    offsetof(struct full_name, arcTitle), 
    offsetof(struct full_name, arcFirstName), 
    offsetof(struct full_name, arcMiddleName), 
    offsetof(struct full_name, arcSurname) 
    }; 

    for (size_t idx = 0; idx < sizeof(offset)/sizeof(offset[0]); ++i) { 
    char *mem_raw_ptr = (char*)fname + offset[idx]; 
    char const *str = *(char const **)mem_raw_ptr; 

    if (strcmp(str, " ") != 0) 
     printf("%s ", str); 
    } 
} 

sicher sein, dass alle Mitglieder Sie "iterieren" über den gleichen Typ! Und denken Sie daran, dass Sie einen Zeiger auf dieses Element berechnen, so dass gegebenenfalls Zeiger auf Zeiger verwendet werden müssen (und möglicherweise, Himmelverbot, Zeiger auf Arrays).

0

Eine Lösung besteht darin, verschiedene Variablennamen demselben Speicherbereich zuzuweisen. Um es so zu behandeln, als hätte es individuelle Variablennamen, während es gleichzeitig die Fähigkeit hat, es als ein Array zu behandeln. Um dies zu erreichen, können wir eine Vereinigung verwenden:

typedef struct 
{ 
    const char* title; 
    const char* firstName; 
    const char* middleName; 
    const char* surname; 
} arcStr; 

typedef struct 
{ 
    ... 
    union 
    { 
    arcStr arc; 
    const char* array[4]; 
    }; 
    ... 
} some_struct; 

Verbrauch: P.strFullName.arc.title.

So ganz ähnlich dem, was Sie bereits, aber Sie können jetzt eine Schleife über diese Daten auch:

for(size_t i=0; i<4; i++) 
{ 
    if (strcmp(P.strFullName.array[i], " ") != 0) 
    printf("%s ", P.strFullName.array[i]); 
}