¿Cómo leo y almaceno cadenas de longitud arbitraria usando malloc y realloc en C?

Tengo una estructura

typedef struct store { char name[11]; int age; } store; 

y una función principal (a continuación es parte de ella):

 int main() { int i=0; int inputs; char line[100]; char name[11]; char command[11]; store read[3000]; while(i < 3000 && gets(line) != NULL) { int tempage; inputs = sscanf(line, "%10s %10s %d", command, name, &tempage); if (inputs == 3) { if (strcmp(command, "register") == 0) { strncpy(read[i].name, name,10); read[i].age = tempage; i++; .... 

Necesito modificarlo para que pueda leer una línea de longitud arbitraria y almacenar el nombre de la línea que también es una cadena de longitud arbitraria usando malloc y realloc.

¿Cómo debo abordar esto?

Lo que debe hacer es leer la línea en incrementos más pequeños y cambiar el tamaño de su búfer a medida que avanza.

Como ejemplo (no probado y no significa que sea particularmente elegante, solo un ejemplo):

 char *readline(FILE *f) { char *buf = NULL; size_t bufsz = 0, len = 0; int keep_going = 1; while (keep_going) { int c = fgetc(f); if (c == EOF || c == '\n') { c = 0; // we'll add zero terminator keep_going = 0; // and terminate the loop afterwards } if (bufsz == len) { // time to resize the buffer. // void *newbuf = NULL; if (!buf) { bufsz = 512; // some arbitrary starting size. newbuf = malloc(bufsz); } else { bufsz *= 2; // issue - ideally you'd check for overflow here. newbuf = realloc(buf, bufsz); } if (!newbuf) { // Allocation failure. Free old buffer (if any) and bail. // free(buf); buf = NULL; break; } buf = newbuf; } buf[len++] = c; } return buf; } 

Cambie el nombre [11] a * nombre; Asigne memoria para eso cada vez que use malloc .

Por cierto, register es una palabra clave en lenguaje C ¡No puedes usarlo como lo hiciste!

Creo que lo que estás buscando es:

 char* name; name = (char*)malloc(sizeof(char)); 

Este enfoque alternativo es similar al de @ asveikau, pero economiza en el uso de malloc () copiando en la stack.

Por favor, no use esto para la respuesta de la tarea.

 #include  #include  #include  char * slurponeline(FILE *f, int s) { const int size = 4096; char buffer[size]; char * r; int c,i=0; while( i=0 && c!='\n')) buffer[i++]=c; if (0 == s && 0 == i) return 0; r = (size==i)? slurponeline(f,s+size):malloc(s+i); memcpy(r+s,buffer,i); return r; } int main(int argc, char ** argv) { FILE * f = fopen(argc>1?argv[1]:"a.out","rb"); char * a,*command,*commandend,*name,*nameend; int age; while (a = slurponeline(f,0)) { char * p = a; while (*p && *p == ' ') ++p; // skip blanks. command = p; while (*p && *p != ' ') ++p; // skip non-blanks. commandend = p; while (*p && *p == ' ') ++p; // skip blanks. name = p; while (*p && *p != ' ') ++p; // skip non-blanks. nameend = p; while (*p && *p == ' ') ++p; // skip blanks. age = atoi(p); *commandend=0; *nameend=0; printf("command: %s, name: %s, age: %d\n",command,name,age); free(a); } }