Allora... Innanzitutto ho guardato tutte le risposte e vi ringrazio per l'attenzione, in particolare non avevo pensato alla strcpy. Sicuramente io non avrò niente da dire sui suggerimenti, sono l'ultimo a poter parlare
Ho finalmente risolto modificando la struttura e inserendo 4 interi, perché mi sono reso conto che una richiesta successiva necessitava dei codici per fare verifiche sulle cifre crescenti e dunque mi son portato avanti.
Per completezza posto il codice per intero (ho aggiunto ancora un paio di funzioncine).
#include <assert.h> //Contiene la macro assert, utilizzata per identificare errori logici ed altri tipi di bug nelle versioni di debug di un programma.
#include <complex.h> //Un gruppo di funzioni usate per manipolare numeri complessi. (Aggiunto con il C99)
#include <ctype.h> //Questo header file contiene funzioni usate per classificare i caratteri in base ai loro tipi o per convertirli da maiuscoli a minuscoli, indipendentemente dal set di caratteri utilizzato (tipicamente ASCII, ma esistono anche implementezioni che usano l'EBCDIC).
#include <errno.h> //Per testare i codici di errore restituiti dalle funzioni di libreria.
#include <fenv.h> //Per controllare l'ambiente in virgola mobile. (Aggiunto con il C99)
#include <float.h> //Contiene delle costanti definite che indicano le proprietà specifiche dell'implementazione della libreria in virgola mobile, come ad esempio la minima differenza tra due numeri in virgola mobile (_EPSILON), il massimo numero di cifre significative (_DIG) e l'intervallo di numeri che possono essere rappresentati (_MIN, _MAX).
#include <inttypes.h> //Per effettuare conversioni precise tra i tipi interi. (Aggiunto con il C99)
#include <iso646.h> //Per programmare nel set di caratteri ISO 646. (Aggiunto con l'NA1)
#include <limits.h> //Contiene delle costanti definite che indicano le proprietà specifiche dell'implementazione dei tipi interi, come l'intervallo dei numeri rappresentabili (_MIN, _MAX).
#include <locale.h> //Per setlocale() e le costanti relative. Utilizzato per scegliere il codice locale adatto.
#include <math.h> //Per le funzioni matematiche comuni.
#include <setjmp.h> //Dichiara setjmp/longjmp, utilizzate per salti non locali.
#include <signal.h> //Per controllare varie condizioni d'eccezione.
#include <stdarg.h> //Utilizzato da funzioni che accettano un numero variabile di parametri.
#include <stdbool.h> //Per un tipo di dato booleano. (Aggiunto con il C99)
#include <stdint.h> //Per definire vari tipi interi. (Aggiunto con il C99)
#include <stddef.h> //Per definire vari tipi e macro utili.
// #include <stdio.h> //Fornisce le funzionalità basilari di input/output del C. Questo file include il prototipo delle venerabili funzioni printf e scanf.
// #include <stdlib.h> //Per eseguire un gran numero di operazioni, tra cui conversioni, generazione di numeri pseudo-casuali, allocazione di memoria, controllo del processo, variabili d'ambiente, segnali, ricerca ed ordinamento.
// #include <string.h> //Per manipolare le stringhe.
#include <tgmath.h> //Per funzioni matematiche di tipo generico. (Aggiunto con il C99)
#include <time.h> //Per convertire tra vari formati di data e ora.
#include <wchar.h> //Per manipolare stream o stringhe contenenti caratteri estesi - fondamentale per supportare una lunga serie di lingue con caratteri non occidentali. (Aggiunto con l'NA1)
#include <wctype.h> //Per la classificazione dei caratteri estesi. (Aggiunto con l'NA1)
#include <stdio.h> //Fornisce le funzionalità basilari di input/output del C. Questo file include il prototipo delle venerabili funzioni printf e scanf.
#include <stdlib.h> //Per eseguire un gran numero di operazioni, tra cui conversioni, generazione di numeri pseudo-casuali, allocazione di memoria, controllo del processo, variabili d'ambiente, segnali, ricerca ed ordinamento.
#include <string.h> //Per manipolare le stringhe.
#define CIFRE_CODICE 4
#define MAX_TENTATIVI 5
#define PARTITE 6
#define MAX_PARTITE (6 * (5 + 1))
/* Strutture usate */
typedef struct CODICE {
int a;
int b;
int c;
int d;
// int num_giocatore;
char tipo; // 'C' se è un codice da indovinare, 'T' se è un codice scritto dal decodificatore e quindi si tratta di un tentativo
} codice;
/* Vettore di strutture (*v) con dimensione (n) */
typedef struct ELENCO_CODICI {
codice *v;
int n;
} elenco_codici;
/* Funzioni usate */
/* Funzione che legge i dati e li sistema bene nella struttura partita */
elenco_codici leggi_dati(char *argv[]) {
/* Apertura file, dichiarazioni di variabili */
FILE *fp;
fp = fopen(argv[1], "r");
char buffer[8];
int i = 0;
int x;
int n = MAX_PARTITE;
codice tmp;
codice *v = malloc(sizeof(codice)*n);
/* C'è un errore */
while(fgets(buffer, sizeof(buffer), fp) != NULL) {
x = sscanf(buffer, "%d %d %d %d", &tmp.a, &tmp.b, &tmp.c, &tmp.d);
if (x == 4) {
v[i] = tmp;
i++;
}
}
n = i;
v = realloc(v, sizeof(codice)*n);
fclose(fp);
// /* Stampa di prova */
// int k;
// for (k = 0; k < n; k++) {
// printf("%d %d %d %d\n", v[k].a, v[k].b, v[k].c, v[k].d);
// }
/* Struttura elenco codici, con dentro l'elenco e il numero di codici totali */
elenco_codici E;
E.v = v;
E.n = n;
return E;
}
/* Funzione che analizza un codice: se è da indovinare assegna 'C' al campo "tipo"
della struct CODICE, altrimenti gli assegna 'T' (tentativo). */
void iscode_ortry(codice *v, int n) {
int i;
int j = 1;
int k;
/* All'inizio sono tutti C */
for (i = 0; i < n; i++)
v[i].tipo = 'C';
i = 0;
/* A ogni giro del ciclo, questo while salta al prossimo codice da indovinare... O almeno dovrebbe */
while (i < n) {
k = 0;
// ERRORE CHE NON RIESCO A SISTEMARE SU C O T
/* Finché i codici sono diversi e ci troviamo entro i 5 tentativi, allora il codice j-esimo è un tentativo T */
while (k == 0 && j < (i + MAX_TENTATIVI + 1) ) {
if (v[i].a != v[j].a || v[i].b != v[j].b || v[i].c != v[j].c || v[i].d != v[j].d) {
k = 0;
} else {
k = 1;
}
v[j].tipo = 'T';
j++;
/* Stampa di prova */
//printf("%c\n", v[j].tipo);
}
i = j;
j++;
}
// /* Stampa di prova */
// for (i = 0; i < n; i++) {
// printf("%d %d %d %d %c\n\n", v[i].a, v[i].b, v[i].c, v[i].d, v[i].tipo);
// }
}
/* Funzione che fa la media dei tentativi effettuati dai giocatori */
void media_tentativi(codice *v, int n) {
int i;
int k = 0;
double media;
for (i = 0; i < n; i++) {
if (v[i].tipo != 'C') {
k++;
}
}
media = (double) k / PARTITE;
printf("[MEDIA_TENTATIVI]\n");
printf("%1.1f\n", media);
}
int main(int argc, char *argv[]) {
elenco_codici E;
E = leggi_dati(argv);
iscode_ortry(E.v, E.n);
/* Richiesta 1 */
media_tentativi(E.v, E.n);
return 0;
}
Grazie ancora per il supporto!
PS: non fate caso alla lista di direttive lassù, è un elenco che mi tengo per me.