malloc the not treated lines of a file
Clash Royale CLAN TAG#URR8PPP
malloc the not treated lines of a file
I've got the following struct
struct JugadorStruct_t
int fichas, manos_ganadas, manos_perdidas;
char* nombre;
int* fichas_partidas;
;
I want to initialize this struct with some values in a txt file, so I do the following:
int initJugador(JugadorPtr_t jugador)
FILE* fp =
fopen("/home/norhther/CLionProjects/blackjack/jugador.txt","r");
if (fp == NULL)
printf("El archivo del jugador no existen");
fclose(fp);
return 1;
else
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)
printf("%s", line);
fclose(fp);
return 0;
(the pre is that the file has at least 4 lines)
I don't know how many lines there is left in the file, but in each remaining line there is a number. I wish to allocate memory and add each value to fichas_partidas.
Is there a nice way to achieve this?
size_t len = 0
And you should use
strcpy
to assign a string to another, so jugador->numbre = strdup(line);
also seems buggy.– adem
Aug 12 at 20:21
strcpy
jugador->numbre = strdup(line);
@adem: That's standard operating procedure with POSIX
getline()
. The function allocates memory as needed — passing a null pointer and zero length is a good way to get started. (The code should free line
after all the input is complete, but that's not a part of the current issue.) Similarly, strdup()
is a POSIX function which allocates the correct space for a copy of the string and copies it.– Jonathan Leffler
Aug 12 at 20:21
getline()
line
strdup()
@adem the call is correct
– P__J__
Aug 12 at 20:21
Generally you'd use a dynamic array (such as ArrayList in Java, std::vector in C++) to store arbitrarily long list of integers. In C, you can roll your own (not many lines of code) or find a suitable library.
– hyde
Aug 12 at 20:29
1 Answer
1
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".
main()
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.
fichas_perdidas
main()
realloc()
malloc()
stderr
#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 existen");
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: %dn", jp->fichas);
printf("Manos Ganadas: %dn", jp->manos_ganadas);
printf("Manos Perdidas: %dn", jp->manos_perdidas);
printf("Num Fichas: %dn", jp->num_fichas);
printf("Max Fichas: %dn", jp->max_fichas);
for (int i = 0; i < jp->num_fichas; i++)
printf("%2d: %dn", 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
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Why did you initialize
size_t len = 0
? Do you want to read 0 bytes from the buffer?– adem
Aug 12 at 20:18