Iterar a través de elementos estructurales del mismo tipo.

C principiante aquí, luchando por encontrar una solución a esto en línea.

Actualmente estoy creando una función para generar datos de la estructura, pero antes de emitir verifica si los datos están presentes.

Esta es mi solución actual:

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"); 

Todos los elementos de estructura aquí son cadenas, y me gustaría idealmente poder recorrer las 2 líneas clave con las funciones if y printf, simplemente cambiando el elemento de estructura en el que el bucle está observando cada incremento.

¿Hay alguna manera de simplificar esto?

Puede escribir una pequeña función que contenga la condición if y también imprima.

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

Luego en el código principal puedes llamarlo como,

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

Esto tiene la ventaja de que tal vez más adelante, si desea agregar otro cheque antes de imprimir, tendrá que hacerse en un solo lugar.

Si realmente debe “iterar”, puede usar la macro offsetof estándar para calcular el desplazamiento de cada miembro, y luego acceder a él a través de la dirección de la estructura:

 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); } } 

¡Asegúrese de que todos los miembros sobre los que "itere" tengan el mismo tipo! Y recuerde que usted calcula un puntero a ese miembro, por lo que los punteros a los punteros pueden necesitar usarse, cuando sea apropiado (y posiblemente, el cielo no lo permita, los punteros a las matrices).

Una solución es usar asignar diferentes nombres de variables a la misma área de memoria. Para tratarlo como si tuviera nombres de variables individuales, mientras que al mismo tiempo tiene la capacidad de tratarlo como una matriz. Para lograrlo, podemos utilizar un sindicato:

 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; 

Uso: P.strFullName.arc.title .

Muy similar a lo que ya tenía, pero ahora también puede pasar por alto estos datos:

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