Here's an adaptation of your code that does what you need. Note that the file name is specified in the main()
program (without an absolute path) and passed to the initialization function. Also note the discussion in Is it a good idea to typedef pointers? — the short answer is "No".
The code adds two fields to the structure to record the maximum number of entries that could be stored in the fichas_perdidas
array, and the actual number of entries that are stored. The allocation code exploits the zero-initialization in main()
and the fact that when passed a null pointer, realloc()
behaves like malloc()
. The allocation code reports the error to standard error; the name stderr
indicates that is intended for error messages.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct JugadorStruct_t
{
int fichas, manos_ganadas, manos_perdidas;
char *nombre;
int *fichas_partidas;
int max_fichas;
int num_fichas;
};
typedef struct JugadorStruct_t *JugadorPtr_t; // Don't do this!
static
int initJugador(JugadorPtr_t jugador, const char *file)
{
FILE *fp = fopen(file, "r");
if (fp == NULL)
{
printf("El archivo del jugador no existe\n");
fclose(fp);
return 1;
}
char *line = NULL;
size_t len = 0;
getline(&line, &len, fp);
jugador->nombre = strdup(line);
getline(&line, &len, fp);
jugador->fichas = atoi(line);
getline(&line, &len, fp);
jugador->manos_ganadas = atoi(line);
getline(&line, &len, fp);
jugador->manos_perdidas = atoi(line);
while (getline(&line, &len, fp) != -1)
{
int x = strtol(line, 0, 0); /* Extremely sloppy */
if (jugador->num_fichas >= jugador->max_fichas)
{
size_t new_number = 2 * jugador->max_fichas + 2;
size_t new_buflen = new_number * sizeof(*jugador);
void *new_buffer = realloc(jugador->fichas_partidas, new_buflen);
if (new_buffer == NULL)
{
fprintf(stderr, "Out of memory (requesting %zu bytes)\n",
new_buflen);
free(jugador->nombre);
free(jugador->fichas_partidas);
fclose(fp);
return -1;
}
jugador->fichas_partidas = new_buffer;
jugador->max_fichas = new_number;
}
jugador->fichas_partidas[jugador->num_fichas++] = x;
}
fclose(fp);
return 0;
}
static void printJugador(const char *tag, struct JugadorStruct_t *jp)
{
printf("%s (%p):\n", tag, (void *)jp);
printf("Nombre: [%s]\n", jp->nombre);
printf("Fichas: %d\n", jp->fichas);
printf("Manos Ganadas: %d\n", jp->manos_ganadas);
printf("Manos Perdidas: %d\n", jp->manos_perdidas);
printf("Num Fichas: %d\n", jp->num_fichas);
printf("Max Fichas: %d\n", jp->max_fichas);
for (int i = 0; i < jp->num_fichas; i++)
printf("%2d: %d\n", i + 1, jp->fichas_partidas[i]);
}
int main(void)
{
struct JugadorStruct_t j = { 0 };
initJugador(&j, "jugador.txt");
printJugador("After reading", &j);
return 0;
}
Sample data file:
Line for nombre
32
27
19
12345
23456
34567
45678
56789
67890
99999999
Output from program:
After reading (0x7ffee84ee400):
Nombre: [Line for nombre
]
Fichas: 32
Manos Ganadas: 27
Manos Perdidas: 19
Num Fichas: 7
Max Fichas: 14
1: 12345
2: 23456
3: 34567
4: 45678
5: 56789
6: 67890
7: 99999999