Pase un contenido de ARCHIVO de tubería a un tamaño desconocido char * (asignación dinámica)

Tengo un FILE * de una tubería (popen), y quiero pasarlo a char *artist . El tamaño de la información que estará en el ARCHIVO es desconocido, por lo que debe usar malloc() .

 FILE *tmp1; char *artist; tmp1 = popen("cmus-remote -Q | grep 'tag artist' | sed s/'tag artist'/''/g | sed '1s/^.//'", "r"); 

¿Cómo puedo hacer esto?

La forma de hacerlo es usar un búfer temporal para leer fragmentos y adjuntarlos al artista de la siguiente manera:

 char buf[8192]; char *artist = NULL; size_t len = 0, total_len = 0; FILE *fp; fp = popen("cmus-remote -Q | grep 'tag artist' | sed s/'tag artist'/''/g | sed '1s/^.//'", "r"); while (!feof(fp)) { if ( fgets(buf, sizeof(buf), fp) == NULL ) break; len = strlen(buf); artist = realloc(artist, len+1); /* +1 for \0 */ if (artist == NULL) { fprintf(stderr, "Ran out of memory\n"); exit(-1); } strncpy(artist+total_len, buf, len+1); /* concatenate the string at the end of artist */ total_len += len; } 

La forma más fácil de hacer esto en una máquina con POSIX getline() es:

 char *buffer = 0; size_t bufsiz = 0; ssize_t nbytes; FILE *tmp1 = popen("cmus-remote -Q | sed -n '/tag artist./ { s/tag artist//g; s/^.//p; }'", "r"); if (tmp1 == 0) …report problem and do not use tmp1… while ((nbytes = getline(tmp1, &buffer, &size)) > 0) { …process line of data… } free(buffer); 

Esto limita sus líneas al tamaño de la memoria asignable; Esto rara vez es una limitación real. Tenga en cuenta que solo necesita un único comando sed para procesar la salida de cmus-remote .