malloc the not treated lines of a file

The name of the pictureThe name of the pictureThe name of the pictureClash 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?





Why did you initialize size_t len = 0? Do you want to read 0 bytes from the buffer?
– adem
Aug 12 at 20:18


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.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard