Tema 6 · Structs i fitxers
Introducció
Una struct (estructura) ens permet agrupar variables de diferents tipus sota un mateix nom, ideal per modelar entitats biomèdiques com proteïnes, pacients o fàrmacs. Amb fitxers podem guardar i recuperar dades de forma permanent, llegint grans volums d'informació des de fitxers FASTA, CSV o text pla.
Objectius
- Definir i utilitzar estructures (
struct) amb camps de diferents tipus - Crear vectors de structs per gestionar col·leccions de dades
- Obtenir, llegir i escriure fitxers de text amb
fopen(),fprintf(),fscanf() - Llegir múltiples proteïnes des d'un fitxer i emmagatzemar-les en un array de structs
Definicions i ús de structs
Una struct per emmagatzemar informació d'una proteïna:
#include <stdio.h>
#include <string.h>
struct Proteina {
char nom[50];
char sequencia[500];
int longitud;
float pes_molecular;
};
int main() {
struct Proteina p1;
strcpy(p1.nom, "Hemoglobina");
strcpy(p1.sequencia, "VLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTT");
p1.longitud = strlen(p1.sequencia);
p1.pes_molecular = p1.longitud * 110.0; // pes mitjà per aminoàcid
printf("Proteïna: %s\n", p1.nom);
printf("Longitud: %d aa\n", p1.longitud);
printf("Pes molecular aproximat: %.1f Da\n", p1.pes_molecular);
return 0;
}
p1.nom
Treballant amb vectors de structs i punters:
#include <stdio.h>
#include <string.h>
#define MAX_PROTEINES 100
struct Proteina {
char nom[50];
char sequencia[500];
int longitud;
};
int main() {
struct Proteina llista[MAX_PROTEINES];
int n = 0;
// Exemple: afegir dues proteïnes manualment
strcpy(llista[0].nom, "Insulina");
strcpy(llista[0].sequencia, "MALWMRLLPLLALLALWGPDPAAA");
llista[0].longitud = strlen(llista[0].sequencia);
strcpy(llista[1].nom, "Glucagó");
strcpy(llista[1].sequencia, "HSQGTFTSDYSKYLDSRRAQDFVQWLMNT");
llista[1].longitud = strlen(llista[1].sequencia);
n = 2;
printf("Llista de proteïnes:\n");
for (int i = 0; i < n; i++) {
printf(" %d. %s (%d aa)\n", i+1, llista[i].nom, llista[i].longitud);
}
return 0;
}
#define MAX_PROTEINES 100 per limitar la mida de l'array
Fitxers: lectura i escriptura
Per treballar amb fitxers fem servir fopen(), fclose() i funcions d'entrada/eixida com fprintf() i fscanf().
#include <stdio.h>
int main() {
FILE *fitxer;
// Escriure en un fitxer
fitxer = fopen("proteines.txt", "w"); // "w" = write (sobreescriu)
if (fitxer == NULL) {
printf("Error en obrir el fitxer.\n");
return 1;
}
fprintf(fitxer, "Insulina 51\n");
fprintf(fitxer, "Glucagó 29\n");
fprintf(fitxer, "Albúmina 585\n");
fclose(fitxer);
// Llegir del fitxer
fitxer = fopen("proteines.txt", "r"); // "r" = read
if (fitxer == NULL) {
printf("Error en obrir el fitxer.\n");
return 1;
}
char nom[50];
int longitud;
printf("Dades llegides del fitxer:\n");
while (fscanf(fitxer, "%s %d", nom, &longitud) == 2) {
printf(" Proteïna: %s, Longitud: %d aa\n", nom, longitud);
}
fclose(fitxer);
return 0;
}
"r" lectura, "w" escriptura, "a" afegir al final
Exemple integrat: structs i fitxers
Llegim múltiples proteïnes des d'un fitxer de text i les guardem en un array de structs. Format del fitxer (proteines.txt):
VLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTT
>Insulina
MALWMRLLPLLALLALWGPDPAAA
Codi per llegir-lo:
#include <stdio.h>
#include <string.h>
#define MAX_PROT 100
#define MAX_SEQ 1000
struct Proteina {
char nom[100];
char sequencia[MAX_SEQ];
int longitud;
};
int main() {
FILE *f = fopen("proteines.txt", "r");
if (f == NULL) {
printf("No s'ha trobat el fitxer.\n");
return 1;
}
struct Proteina llista[MAX_PROT];
int total = 0;
char linia[MAX_SEQ];
while (fgets(linia, MAX_SEQ, f) != NULL && total < MAX_PROT) {
// La línia comença amb '>' → capçalera
if (linia[0] == '>') {
linia[strcspn(linia, "\n")] = '\0'; // treure '\n'
strcpy(llista[total].nom, linia + 1); // saltar el '>'
llista[total].sequencia[0] = '\0';
llista[total].longitud = 0;
} else {
// És línia de seqüència
linia[strcspn(linia, "\n")] = '\0';
strcat(llista[total].sequencia, linia);
llista[total].longitud = strlen(llista[total].sequencia);
total++; // cada seqüència completa → següent proteïna
}
}
fclose(f);
printf("Proteïnes llegides: %d\n\n", total);
for (int i = 0; i < total; i++) {
printf("--- %s ---\n", llista[i].nom);
printf("Seqüència: %s\n", llista[i].sequencia);
printf("Longitud: %d aa\n\n", llista[i].longitud);
}
return 0;
}
Exercicis
- Defineix una
struct Medicamentamb nom, dosi i preu. Crea 3 medicaments i mostra'ls per pantalla. - Escriu un programa que guardi en un fitxer de text les dades de 5 pacients (nom, edat, diagnòstic) i després les torni a llegir.
- Amplia l'exemple de proteïnes per calcular també el percentatge d'aminoàcids hidrofòbics (A, V, L, I, P, F, W, M) i guarda el resultat en un fitxer de sortida.
Mini Projecte – Lectura automàtica de múltiples proteïnes
Escriu un programa que:
- Llegeixi un fitxer en format FASTA simplificat amb diverses proteïnes (capçalera
>nom+ seqüència en una o vàries línies). - Emmagatzemi cada proteïna en una
struct(nom, seqüència, longitud). - Calculi per a cada proteïna: longitud, pes molecular aproximat, percentatge d'aminoàcids carregats (K, R, D, E).
- Generi un fitxer de sortida
resum_proteines.txtamb un informe tabulat. - Utilitzi funcions separades:
llegirProteines(),calcularEstadistiques(),escriureInforme().
Pista: defineix la struct com a tipus global amb typedef struct { ... } Proteina; per simplificar el codi.