Defineix una struct Medicament amb nom, dosi i preu. Crea 3 medicaments i mostra'ls per pantalla.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strcpy() */
/* Definició de l'estructura Medicament */
/* Una estructura (struct) agrupa variables de diferents tipus sota un sol nom */
/* Cada variable dins de l'estructura s'anomena "camp" o "membre" */
struct Medicament { /* 'struct Medicament' és el nom del tipus */
char nom[50]; /* Camp per al nom del medicament (cadena de fins a 49 caràcters + '\0') */
/* Es reserva espai fix dins de l'estructura */
float dosi; /* Camp per a la dosi en mg (nombre decimal) */
/* float ocupa 4 bytes en memòria */
float preu; /* Camp per al preu en euros (nombre decimal) */
}; /* El punt i coma al final és obligatori en la definició d'estructures */
/* Funció auxiliar per mostrar un medicament */
/* Rep un punter a struct Medicament per evitar copiar tota l'estructura */
/* const indica que la funció no modificarà les dades */
void mostrar_medicament(const struct Medicament *med){ /* Paràmetre: punter constant a Medicament */
printf(" Nom: %s\n", med->nom); /* Accedeix al camp 'nom' amb l'operador fletxa (->) */
/* med->nom és equivalent a (*med).nom */
/* L'operador -> s'usa amb punters a estructures */
printf(" Dosi: %.2f mg\n", med->dosi); /* Mostra la dosi amb 2 decimals */
printf(" Preu: %.2f euros\n", med->preu); /* Mostra el preu amb 2 decimals */
}
int main(){ /* Funció principal del programa */
/* Declaració i inicialització de 3 medicaments */
/* Es poden inicialitzar camps en la declaració amb claus {} */
struct Medicament med1 = {"Paracetamol", 500.0, 3.50}; /* Inicialització completa */
/* Els valors s'assignen en ordre: nom, dosi, preu */
struct Medicament med2 = {"Ibuprofen", 600.0, 5.75}; /* Segon medicament */
struct Medicament med3; /* Declaració sense inicialitzar */
/* Els camps contenen valors indeterminats (escombraries) */
/* Assignació de valors als camps un per un */
strcpy(med3.nom, "Amoxicilina"); /* strcpy() copia la cadena al camp nom */
/* No es pot fer med3.nom = "Amoxicilina" perquè és un array */
med3.dosi = 250.0; /* Assigna la dosi amb l'operador punt (.) */
/* L'operador . s'usa amb variables d'estructura (no punters) */
med3.preu = 8.20; /* Assigna el preu */
/* Mostra els medicaments per pantalla */
printf("=== FARMACIA - LLISTAT DE MEDICAMENTS ===\n\n");
printf("Medicament 1:\n"); /* Etiqueta */
mostrar_medicament(&med1); /* Passa l'adreça de med1 a la funció */
/* &med1 obté el punter a l'estructura */
printf("\n");
printf("Medicament 2:\n");
mostrar_medicament(&med2); /* Passa l'adreça de med2 */
printf("\n");
printf("Medicament 3:\n");
mostrar_medicament(&med3); /* Passa l'adreça de med3 */
printf("\n");
/* Càlcul del preu total dels 3 medicaments */
float preu_total = med1.preu + med2.preu + med3.preu; /* Suma els camps preu */
printf("Preu total dels 3 medicaments: %.2f euros\n", preu_total);
/* Mostra la mida de l'estructura en bytes */
printf("\nInformacio tecnica:\n");
printf(" Mida de struct Medicament: %d bytes\n", (int)sizeof(struct Medicament));
/* sizeof() retorna la mida total de l'estructura en bytes */
/* Inclou possibles bytes de farciment (padding) per alineació */
return 0; /* Finalitza el programa amb èxit */
}
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.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf(), scanf(), fopen(), fprintf(), fscanf(), fclose() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Definició de l'estructura Pacient */
struct Pacient { /* Agrupa les dades d'un pacient */
char nom[50]; /* Nom del pacient (fins a 49 caràcters) */
int edat; /* Edat del pacient (nombre enter) */
char diagnostic[100]; /* Diagnòstic (fins a 99 caràcters) */
};
/* Funció per escriure les dades dels pacients a un fitxer */
/* Rep un array de pacients i el nombre de pacients */
void escriure_fitxer(struct Pacient pacients[], int n){ /* Array d'estructures i mida */
/* Obre el fitxer en mode escriptura ("w") */
FILE *fitxer = fopen("pacients.txt", "w"); /* fopen() obre/crea un fitxer */
/* "pacients.txt": nom del fitxer */
/* "w": mode escriptura (write) */
/* Si el fitxer existeix, es sobreescriu */
/* Si no existeix, es crea */
if(fitxer == NULL){ /* Verifica que el fitxer s'ha obert correctament */
/* fopen() retorna NULL si hi ha error */
printf("Error: No s'ha pogut crear el fitxer pacients.txt\n");
return; /* Surt de la funció sense fer res més */
}
printf("Escrivint dades al fitxer...\n");
/* Escriu una capçalera al fitxer */
fprintf(fitxer, "=== LLISTAT DE PACIENTS ===\n\n"); /* fprintf() escriu text formatat al fitxer */
/* Funciona igual que printf() però sobre un fitxer */
/* Bucle per escriure cada pacient */
for(int i = 0; i < n; i++){ /* Recorre l'array de pacients */
/* Escriu les dades del pacient en format estructurat */
fprintf(fitxer, "Pacient %d:\n", i + 1); /* Número de pacient */
fprintf(fitxer, " Nom: %s\n", pacients[i].nom); /* Nom */
fprintf(fitxer, " Edat: %d anys\n", pacients[i].edat); /* Edat */
fprintf(fitxer, " Diagnostic: %s\n", pacients[i].diagnostic); /* Diagnòstic */
fprintf(fitxer, "\n"); /* Línia en blanc entre pacients */
}
fclose(fitxer); /* Tanca el fitxer */
/* És MOLT IMPORTANT tancar el fitxer: assegura que les dades s'escriguin al disc */
/* Si no es tanca, es poden perdre dades */
printf("Fitxer 'pacients.txt' creat correctament!\n");
}
/* Funció per llegir les dades dels pacients des del fitxer */
void llegir_fitxer(){ /* No rep paràmetres, llegeix directament del fitxer */
/* Obre el fitxer en mode lectura ("r") */
FILE *fitxer = fopen("pacients.txt", "r"); /* "r": mode lectura (read) */
/* El fitxer ha d'existir */
if(fitxer == NULL){ /* Si el fitxer no es pot obrir (no existeix, permisos, etc.) */
printf("Error: No s'ha pogut obrir el fitxer pacients.txt\n");
printf(" Assegura't que el fitxer existeix.\n");
return;
}
printf("\nLlegint dades del fitxer...\n");
printf("========================================\n");
char linia[200]; /* Buffer per llegir cada línia del fitxer */
/* 200 caràcters és suficient per a una línia */
/* Bucle per llegir el fitxer línia per línia */
/* fgets() llegeix una línia completa (fins a newline o final de fitxer) */
while(fgets(linia, sizeof(linia), fitxer) != NULL){ /* Mentre hi hagi línies per llegir */
/* fgets() retorna NULL quan arriba al final del fitxer */
/* sizeof(linia) és la mida màxima a llegir (200) */
printf("%s", linia); /* Mostra la línia llegida */
/* No cal \n perquè fgets() inclou el salt de línia */
}
fclose(fitxer); /* Tanca el fitxer després de llegir */
printf("========================================\n");
}
int main(){ /* Funció principal */
/* Declara i inicialitza un array de 5 pacients */
struct Pacient pacients[5] = { /* Array de 5 estructures Pacient */
{"Anna Garcia", 35, "Hipertensio arterial"}, /* Pacient 0 */
{"Joan Martinez", 42, "Diabetis tipus 2"}, /* Pacient 1 */
{"Maria Lopez", 28, "Migranya cronica"}, /* Pacient 2 */
{"Pere Sanchez", 55, "Artrosi de genoll"}, /* Pacient 3 */
{"Laura Vidal", 31, "Asma bronquial"} /* Pacient 4 */
};
/* Mostra les dades en memòria */
printf("=== DADES DELS PACIENTS EN MEMORIA ===\n");
for(int i = 0; i < 5; i++){
printf("Pacient %d: %s, %d anys - %s\n",
i + 1, pacients[i].nom, pacients[i].edat, pacients[i].diagnostic);
}
/* Escriu les dades al fitxer */
printf("\n");
escriure_fitxer(pacients, 5); /* Passa l'array i el nombre d'elements */
/* Llegeix i mostra el contingut del fitxer */
llegir_fitxer(); /* No necessita paràmetres, llegeix directament */
/* Demostració addicional: llegir amb fscanf() (lectura formatada) */
printf("\n=== LECTURA AMB FSCANF (DEMOSTRACIO) ===\n");
FILE *fitxer2 = fopen("pacients.txt", "r");
if(fitxer2 != NULL){
struct Pacient pacient_llegit; /* Estructura temporal per llegir */
char temp[100]; /* Buffer per a text no rellevant */
/* Llegeix ignorant les línies de capçalera */
fgets(temp, 100, fitxer2); /* Línia "=== LLISTAT..." */
fgets(temp, 100, fitxer2); /* Línia en blanc */
/* Intenta llegir 5 pacients amb fscanf() */
for(int i = 0; i < 5; i++){
/* fscanf() llegeix dades formatades d'un fitxer */
/* El format ha de coincidir exactament amb com es va escriure */
int llegits = fscanf(fitxer2, "Pacient %*d:\n Nom: %[^\n]\n Edat: %d anys\n Diagnostic: %[^\n]\n\n",
pacient_llegit.nom, &pacient_llegit.edat, pacient_llegit.diagnostic);
/* %*d: llegeix un enter però l'ignora (el número de pacient) */
/* %[^\n]: llegeix tots els caràcters fins a newline (per noms amb espais) */
if(llegits == 3){ /* Si s'han llegit els 3 camps correctament */
printf("Llegit: %s, %d anys - %s\n",
pacient_llegit.nom, pacient_llegit.edat, pacient_llegit.diagnostic);
}
}
fclose(fitxer2);
}
return 0; /* Finalitza el programa amb èxit */
}
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.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf() i gestió de fitxers */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strlen() */
#include <ctype.h> /* Inclou la biblioteca per a classificació de caràcters */
/* Necessària per a toupper() */
/* Estructura per emmagatzemar informació d'una proteïna */
struct Proteina { /* Agrupa les dades rellevants d'una proteïna */
char nom[50]; /* Nom o identificador de la proteïna */
char sequencia[500]; /* Seqüència d'aminoàcids (fins a 499 caràcters) */
/* En una aplicació real, podria ser memòria dinàmica */
int longitud; /* Longitud de la seqüència (nombre d'aminoàcids) */
int hidrofobics; /* Nombre d'aminoàcids hidrofòbics */
float pct_hidrofobics; /* Percentatge d'aminoàcids hidrofòbics */
};
/* Funció per comprovar si un aminoàcid és hidrofòbic */
/* Retorna 1 (cert) si ho és, 0 (fals) si no */
int es_hidrofobic(char aa){ /* Rep un caràcter (aminoàcid en codi d'una lletra) */
/* Converteix a majúscula per fer la comprovació insensible a majúscules/minúscules */
aa = toupper(aa); /* toupper() retorna la versió majúscula del caràcter */
/* Comprova si l'aminoàcid és un dels 8 hidrofòbics */
/* Aminoàcids hidrofòbics: Alanina(A), Valina(V), Leucina(L), Isoleucina(I),
Prolina(P), Fenilalanina(F), Triptòfan(W), Metionina(M) */
if(aa == 'A' || aa == 'V' || aa == 'L' || aa == 'I' ||
aa == 'P' || aa == 'F' || aa == 'W' || aa == 'M')
return 1; /* És hidrofòbic */
else
return 0; /* No és hidrofòbic (és hidrofílic o altre) */
}
/* Funció per analitzar una proteïna i omplir els seus camps calculats */
void analitzar_proteina(struct Proteina *prot){ /* Rep un punter per modificar l'estructura */
prot->longitud = strlen(prot->sequencia); /* Calcula la longitud amb strlen() */
/* -> accedeix als camps a través del punter */
prot->hidrofobics = 0; /* Inicialitza el comptador a 0 */
/* Bucle per comptar els aminoàcids hidrofòbics */
for(int i = 0; i < prot->longitud; i++){ /* Recorre tota la seqüència */
if(es_hidrofobic(prot->sequencia[i])) /* Comprova cada aminoàcid */
prot->hidrofobics++; /* Incrementa el comptador si és hidrofòbic */
}
/* Calcula el percentatge d'hidrofòbics */
if(prot->longitud > 0) /* Evita la divisió per zero */
prot->pct_hidrofobics = (float)prot->hidrofobics / prot->longitud * 100;
else
prot->pct_hidrofobics = 0.0; /* Si no hi ha seqüència, percentatge 0 */
}
/* Funció per mostrar l'anàlisi per pantalla */
void mostrar_analisi(const struct Proteina *prot){ /* const: no modifica l'estructura */
printf("Proteina: %s\n", prot->nom);
printf(" Sequencia: %s\n", prot->sequencia);
printf(" Longitud: %d aminoacids\n", prot->longitud);
printf(" Hidrofobics: %d (%.1f%%)\n", prot->hidrofobics, prot->pct_hidrofobics);
printf(" Hidrofilics: %d (%.1f%%)\n",
prot->longitud - prot->hidrofobics, 100.0 - prot->pct_hidrofobics);
/* Els hidrofílics són la resta d'aminoàcids */
}
/* Funció per guardar l'anàlisi en un fitxer */
void guardar_analisi_fitxer(struct Proteina proteines[], int n, const char* nom_fitxer){
/* Obre el fitxer en mode escriptura */
FILE *fitxer = fopen(nom_fitxer, "w"); /* El nom del fitxer es rep com a paràmetre */
if(fitxer == NULL){
printf("Error: No s'ha pogut crear el fitxer %s\n", nom_fitxer);
return;
}
/* Escriu la capçalera del fitxer */
fprintf(fitxer, "========================================\n");
fprintf(fitxer, " ANALISI D'AMINOACIDS HIDROFOBICS\n");
fprintf(fitxer, "========================================\n\n");
/* Escriu un resum tabulat */
fprintf(fitxer, "%-20s %8s %10s %10s\n", "PROTEINA", "LONGITUD", "HIDROFOBICS", "%HIDROFOB.");
/* %-20s: cadena de 20 caràcters alineada a l'esquerra */
/* %8s, %10s: columnes de 8 i 10 caràcters alineades a la dreta */
fprintf(fitxer, "----------------------------------------\n");
/* Escriu les dades de cada proteïna */
for(int i = 0; i < n; i++){
fprintf(fitxer, "%-20s %8d %10d %9.1f%%\n",
proteines[i].nom,
proteines[i].longitud,
proteines[i].hidrofobics,
proteines[i].pct_hidrofobics);
}
fprintf(fitxer, "----------------------------------------\n\n");
/* Escriu el detall de cada proteïna */
for(int i = 0; i < n; i++){
fprintf(fitxer, "Proteina: %s\n", proteines[i].nom);
fprintf(fitxer, " Sequencia: %s\n", proteines[i].sequencia);
/* Mostra la seqüència marcant els hidrofòbics amb asterisc */
fprintf(fitxer, " Marcatge: ");
for(int j = 0; j < proteines[i].longitud; j++){
fprintf(fitxer, "%c", proteines[i].sequencia[j]);
}
fprintf(fitxer, "\n Hidrofob: ");
for(int j = 0; j < proteines[i].longitud; j++){
if(es_hidrofobic(proteines[i].sequencia[j]))
fprintf(fitxer, "*"); /* Asterisc per als hidrofòbics */
else
fprintf(fitxer, " "); /* Espai per als no hidrofòbics */
}
fprintf(fitxer, "\n\n");
}
fclose(fitxer); /* Tanca el fitxer */
printf("Fitxer '%s' creat correctament!\n", nom_fitxer);
}
int main(){ /* Funció principal */
/* Declara i inicialitza 3 proteïnes d'exemple */
struct Proteina proteines[3] = {
{"Insulina", "MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKT", 0, 0, 0.0},
/* Seqüència real de la insulina humana (cadena B + C + A simplificada) */
{"Hemoglobina_A", "MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTTKTYFPHFDLSHGSAQVKGHGKKVADALTNAVAHVDDMPNALSALSDLHAHKLRVDPVNFKLLSHCLLVTLAAHLPAEFTPAVHASLDKFLASVSTVLTSKYR", 0, 0, 0.0},
/* Fragment de la cadena alfa de l'hemoglobina */
{"Colagen", "GPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPMGPM", 0, 0, 0.0}
/* Seqüència repetitiva típica del col·lagen (Gly-Pro-Met) */
};
int num_proteines = 3; /* Nombre de proteïnes a analitzar */
/* Analitza cada proteïna */
for(int i = 0; i < num_proteines; i++){
analitzar_proteina(&proteines[i]); /* Passa l'adreça per modificar l'estructura */
}
/* Mostra els resultats per pantalla */
printf("=== ANALISI D'AMINOACIDS HIDROFOBICS ===\n\n");
for(int i = 0; i < num_proteines; i++){
mostrar_analisi(&proteines[i]);
printf("\n");
}
/* Guarda els resultats al fitxer */
guardar_analisi_fitxer(proteines, num_proteines, "analisi_hidrofobics.txt");
/* Llegeix i mostra el contingut del fitxer creat */
printf("\n=== CONTINGUT DEL FITXER GENERAT ===\n");
FILE *fitxer = fopen("analisi_hidrofobics.txt", "r");
if(fitxer != NULL){
char linia[200];
while(fgets(linia, sizeof(linia), fitxer) != NULL){
printf("%s", linia); /* Mostra cada línia */
}
fclose(fitxer);
}
return 0; /* Finalitza el programa amb èxit */
}
Escriu un programa que llegeixi un fitxer FASTA, analitzi múltiples proteïnes i generi un informe.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf(), fopen(), fprintf(), fgets(), fclose() */
#include <stdlib.h> /* Inclou la biblioteca estàndard */
/* Necessària per a malloc(), realloc(), free(), atof() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strlen(), strcpy(), strcat(), strchr() */
#include <ctype.h> /* Inclou la biblioteca per a classificació de caràcters */
/* Necessària per a toupper(), isspace() */
/* Constants del programa */
#define MAX_PROTEINES 50 /* Nombre màxim de proteïnes a processar */
#define MAX_NOM 100 /* Longitud màxima del nom d'una proteïna */
#define MAX_LINIA 1000 /* Longitud màxima d'una línia del fitxer */
/* Definició de l'estructura Proteina com a tipus global amb typedef */
/* typedef crea un àlies: podem usar 'Proteina' en lloc de 'struct Proteina' */
typedef struct { /* Estructura per emmagatzemar una proteïna completa */
char nom[MAX_NOM]; /* Nom o capçalera de la proteïna (sense el '>') */
char *sequencia; /* Punter a la seqüència (memòria dinàmica) */
/* S'usa memòria dinàmica perquè la longitud pot variar */
int longitud; /* Longitud de la seqüència (nombre d'aminoàcids) */
float pes_molecular; /* Pes molecular aproximat en Daltons (Da) */
int carregats; /* Nombre d'aminoàcids carregats (K, R, D, E) */
float pct_carregats; /* Percentatge d'aminoàcids carregats */
int hidrofobics; /* Nombre d'aminoàcids hidrofòbics */
float pct_hidrofobics; /* Percentatge d'aminoàcids hidrofòbics */
} Proteina; /* 'Proteina' és ara un nom de tipus vàlid */
/* Array global de proteïnes */
Proteina proteines[MAX_PROTEINES]; /* Array d'estructures Proteina */
int total_proteines = 0; /* Comptador de proteïnes llegides */
/* Prototips de les funcions principals */
int llegirProteines(const char* nom_fitxer); /* Llegeix proteïnes d'un fitxer FASTA */
/* Retorna el nombre de proteïnes llegides */
void calcularEstadistiques(); /* Calcula estadístiques per a cada proteïna */
void escriureInforme(const char* nom_fitxer); /* Genera el fitxer d'informe */
void alliberarMemoria(); /* Allibera tota la memòria dinàmica */
/* Funcions auxiliars per al càlcul de propietats */
int es_carregat(char aa); /* Comprova si un aminoàcid és carregat (K,R,D,E) */
int es_hidrofobic(char aa); /* Comprova si un aminoàcid és hidrofòbic */
float pes_aminoacid(char aa); /* Retorna el pes molecular d'un aminoàcid */
int main(){ /* Funció principal del programa */
char nom_fitxer_entrada[100]; /* Nom del fitxer FASTA a llegir */
printf("========================================\n");
printf(" ANALITZADOR DE PROTEINES (FASTA)\n");
printf("========================================\n\n");
/* Demana el nom del fitxer d'entrada */
printf("Nom del fitxer FASTA d'entrada: ");
scanf("%99s", nom_fitxer_entrada);
/* Pas 1: Llegir les proteïnes del fitxer */
printf("\nLlegint proteines de '%s'...\n", nom_fitxer_entrada);
int llegides = llegirProteines(nom_fitxer_entrada);
if(llegides == 0){ /* Si no s'ha llegit cap proteïna */
printf("No s'han trobat proteïnes al fitxer.\n");
printf("Assegura't que el fitxer existeix i te format FASTA correcte.\n");
return 1; /* Surt amb error */
}
printf("S'han llegit %d proteines correctament.\n", llegides);
/* Pas 2: Calcular estadístiques */
printf("\nCalculant estadistiques...\n");
calcularEstadistiques();
/* Mostra un resum per pantalla */
printf("\n=== RESUM PER PANTALLA ===\n");
printf("%-20s %8s %10s %10s %10s\n", "PROTEINA", "LONGITUD", "PES (Da)", "%CARREGATS", "%HIDROFOB.");
printf("------------------------------------------------------------\n");
for(int i = 0; i < total_proteines; i++){
printf("%-20s %8d %10.1f %9.1f%% %9.1f%%\n",
proteines[i].nom,
proteines[i].longitud,
proteines[i].pes_molecular,
proteines[i].pct_carregats,
proteines[i].pct_hidrofobics);
}
/* Pas 3: Generar l'informe */
printf("\nGenerant informe...\n");
escriureInforme("resum_proteines.txt");
/* Allibera la memòria dinàmica */
alliberarMemoria();
printf("Memoria alliberada. Programa finalitzat.\n");
return 0; /* Finalitza amb èxit */
}
/* Funció per llegir proteïnes d'un fitxer en format FASTA */
int llegirProteines(const char* nom_fitxer){
/* Obre el fitxer en mode lectura */
FILE *fitxer = fopen(nom_fitxer, "r"); /* "r": mode lectura */
if(fitxer == NULL){
printf("Error: No s'ha pogut obrir el fitxer '%s'.\n", nom_fitxer);
return 0; /* Retorna 0 proteïnes llegides */
}
char linia[MAX_LINIA]; /* Buffer per a cada línia del fitxer */
char sequencia_temp[10000]; /* Buffer temporal per construir la seqüència */
/* En producció, s'usaria memòria dinàmica incremental */
int dins_proteina = 0; /* Bandera: indica si estem processant una proteïna */
/* 0 = no, 1 = sí */
total_proteines = 0; /* Inicialitza el comptador global */
/* Bucle de lectura línia per línia */
while(fgets(linia, MAX_LINIA, fitxer) != NULL && total_proteines < MAX_PROTEINES){
/* fgets() llegeix fins a newline, final de fitxer o MAX_LINIA-1 caràcters */
/* Retorna NULL quan arriba al final del fitxer */
/* Elimina el salt de línia final si existeix */
int len = strlen(linia);
if(len > 0 && linia[len-1] == '\n')
linia[len-1] = '\0'; /* Substitueix '\n' per '\0' */
/* Comprova si la línia és una capçalera FASTA (comença amb '>') */
if(linia[0] == '>'){ /* Format FASTA: >nom_de_la_proteina */
/* Si ja estàvem processant una proteïna, la guardem */
if(dins_proteina && total_proteines < MAX_PROTEINES){
/* Reserva memòria exacta per a la seqüència */
int long_seq = strlen(sequencia_temp);
proteines[total_proteines].sequencia = (char*)malloc((long_seq + 1) * sizeof(char));
/* malloc() reserva memòria per a la seqüència + '\0' */
if(proteines[total_proteines].sequencia != NULL){
strcpy(proteines[total_proteines].sequencia, sequencia_temp);
/* Copia la seqüència acumulada a la memòria dinàmica */
}
total_proteines++; /* Incrementa el comptador */
}
/* Inicia una nova proteïna */
/* Copia el nom sense el caràcter '>' inicial */
strcpy(proteines[total_proteines].nom, linia + 1);
/* linia + 1: punter al segon caràcter (saltant el '>') */
proteines[total_proteines].sequencia = NULL; /* Encara no té seqüència */
proteines[total_proteines].longitud = 0;
sequencia_temp[0] = '\0'; /* Reinicia el buffer de seqüència */
dins_proteina = 1; /* Marca que estem dins d'una proteïna */
} else if(dins_proteina && strlen(linia) > 0){ /* Línia de seqüència */
/* Concatena la línia al buffer de seqüència */
strcat(sequencia_temp, linia); /* strcat() afegeix al final */
/* Nota: cal assegurar que sequencia_temp té prou espai */
}
}
/* Guarda l'última proteïna (si n'hi ha) */
if(dins_proteina && total_proteines < MAX_PROTEINES){
int long_seq = strlen(sequencia_temp);
proteines[total_proteines].sequencia = (char*)malloc((long_seq + 1) * sizeof(char));
if(proteines[total_proteines].sequencia != NULL){
strcpy(proteines[total_proteines].sequencia, sequencia_temp);
}
total_proteines++;
}
fclose(fitxer); /* Tanca el fitxer */
return total_proteines; /* Retorna el nombre de proteïnes llegides */
}
/* Funció per calcular estadístiques de totes les proteïnes */
void calcularEstadistiques(){
for(int i = 0; i < total_proteines; i++){ /* Per a cada proteïna */
if(proteines[i].sequencia == NULL) continue; /* Salta si no té seqüència */
proteines[i].longitud = strlen(proteines[i].sequencia);
proteines[i].carregats = 0;
proteines[i].hidrofobics = 0;
proteines[i].pes_molecular = 0.0;
/* Analitza cada aminoàcid de la seqüència */
for(int j = 0; j < proteines[i].longitud; j++){
char aa = toupper(proteines[i].sequencia[j]); /* Converteix a majúscula */
/* Comptatge d'aminoàcids carregats */
if(es_carregat(aa))
proteines[i].carregats++;
/* Comptatge d'aminoàcids hidrofòbics */
if(es_hidrofobic(aa))
proteines[i].hidrofobics++;
/* Acumulació del pes molecular */
proteines[i].pes_molecular += pes_aminoacid(aa);
}
/* Càlcul de percentatges */
if(proteines[i].longitud > 0){
proteines[i].pct_carregats = (float)proteines[i].carregats / proteines[i].longitud * 100;
proteines[i].pct_hidrofobics = (float)proteines[i].hidrofobics / proteines[i].longitud * 100;
}
}
}
/* Funció per generar l'informe en un fitxer de text */
void escriureInforme(const char* nom_fitxer){
FILE *fitxer = fopen(nom_fitxer, "w"); /* Obre en mode escriptura */
if(fitxer == NULL){
printf("Error: No s'ha pogut crear el fitxer '%s'.\n", nom_fitxer);
return;
}
/* Capçalera de l'informe */
fprintf(fitxer, "================================================================\n");
fprintf(fitxer, " INFORME D'ANALISI DE PROTEINES\n");
fprintf(fitxer, "================================================================\n\n");
fprintf(fitxer, "Data de l'informe: (automatic)\n");
fprintf(fitxer, "Nombre de proteines analitzades: %d\n\n", total_proteines);
/* Taula resum */
fprintf(fitxer, "--- TAULA RESUM ---\n\n");
fprintf(fitxer, "%-25s %8s %12s %10s %10s %10s\n",
"PROTEINA", "LONGITUD", "PES MOLEC.", "%CARREGATS", "%HIDROFOB.", "CARREGA");
fprintf(fitxer, "%-25s %8s %12s %10s %10s %10s\n",
"-------------------------", "--------", "------------", "----------", "----------", "----------");
for(int i = 0; i < total_proteines; i++){
/* Determina la càrrega predominant */
char tipus_carrega[10];
if(proteines[i].pct_carregats > 20.0)
strcpy(tipus_carrega, "ALTA");
else if(proteines[i].pct_carregats > 10.0)
strcpy(tipus_carrega, "MITJANA");
else
strcpy(tipus_carrega, "BAIXA");
fprintf(fitxer, "%-25s %8d %10.1f Da %9.1f%% %9.1f%% %10s\n",
proteines[i].nom,
proteines[i].longitud,
proteines[i].pes_molecular,
proteines[i].pct_carregats,
proteines[i].pct_hidrofobics,
tipus_carrega);
}
/* Detall de cada proteïna */
fprintf(fitxer, "\n\n--- DETALL PER PROTEINA ---\n\n");
for(int i = 0; i < total_proteines; i++){
fprintf(fitxer, "Proteina: %s\n", proteines[i].nom);
fprintf(fitxer, " Longitud: %d aminoacids\n", proteines[i].longitud);
fprintf(fitxer, " Pes molecular aproximat: %.1f Da\n", proteines[i].pes_molecular);
fprintf(fitxer, " Aminoacids carregats (K,R,D,E): %d (%.1f%%)\n",
proteines[i].carregats, proteines[i].pct_carregats);
fprintf(fitxer, " Aminoacids hidrofobics: %d (%.1f%%)\n",
proteines[i].hidrofobics, proteines[i].pct_hidrofobics);
/* Mostra la seqüència amb marques */
if(proteines[i].longitud <= 100){ /* Només si és curta */
fprintf(fitxer, " Sequencia: %s\n", proteines[i].sequencia);
fprintf(fitxer, " Carregats: ");
for(int j = 0; j < proteines[i].longitud; j++){
if(es_carregat(toupper(proteines[i].sequencia[j])))
fprintf(fitxer, "+"); /* Marca els carregats */
else
fprintf(fitxer, ".");
}
fprintf(fitxer, "\n");
}
fprintf(fitxer, "\n");
}
fclose(fitxer); /* Tanca el fitxer */
printf("Informe guardat a '%s'.\n", nom_fitxer);
}
/* Funció per alliberar tota la memòria dinàmica reservada */
void alliberarMemoria(){
for(int i = 0; i < total_proteines; i++){
if(proteines[i].sequencia != NULL){ /* Si té seqüència reservada */
free(proteines[i].sequencia); /* Allibera la memòria */
proteines[i].sequencia = NULL; /* Evita punters penjants */
}
}
}
/* Funció auxiliar: comprova si un aminoàcid és carregat */
int es_carregat(char aa){
/* Aminoàcids carregats: Lisina(K), Arginina(R) -> positius */
/* Aspartat(D), Glutamat(E) -> negatius */
aa = toupper(aa);
return (aa == 'K' || aa == 'R' || aa == 'D' || aa == 'E');
}
/* Funció auxiliar: comprova si un aminoàcid és hidrofòbic */
int es_hidrofobic(char aa){
aa = toupper(aa);
return (aa == 'A' || aa == 'V' || aa == 'L' || aa == 'I' ||
aa == 'P' || aa == 'F' || aa == 'W' || aa == 'M');
}
/* Funció auxiliar: retorna el pes molecular d'un aminoàcid */
float pes_aminoacid(char aa){
/* Pesos moleculars aproximats en Daltons (Da) */
/* Valors simplificats per a l'exercici */
switch(toupper(aa)){
case 'A': return 89.1; /* Alanina */
case 'R': return 174.2; /* Arginina */
case 'N': return 132.1; /* Asparagina */
case 'D': return 133.1; /* Aspartat */
case 'C': return 121.2; /* Cisteina */
case 'E': return 147.1; /* Glutamat */
case 'Q': return 146.2; /* Glutamina */
case 'G': return 75.1; /* Glicina */
case 'H': return 155.2; /* Histidina */
case 'I': return 131.2; /* Isoleucina */
case 'L': return 131.2; /* Leucina */
case 'K': return 146.2; /* Lisina */
case 'M': return 149.2; /* Metionina */
case 'F': return 165.2; /* Fenilalanina */
case 'P': return 115.1; /* Prolina */
case 'S': return 105.1; /* Serina */
case 'T': return 119.1; /* Treonina */
case 'W': return 204.2; /* Triptofan */
case 'Y': return 181.2; /* Tirosina */
case 'V': return 117.1; /* Valina */
default: return 110.0; /* Pes mitjà per a aminoàcids desconeguts */
}
/* Nota: el pes molecular real d'una proteïna requereix */
/* sumar els pesos i restar H2O per cada enllaç peptídic */
}