Leyendo todo el archivo de texto en una matriz char en C

Quiero leer el contenido de un archivo de texto en una matriz char en C. Deben mantenerse las líneas nuevas.

¿Cómo logro esto? Encontré algunas soluciones de C ++ en la web, pero ninguna solución de C solo.

Editar: ahora tengo el siguiente código:

void *loadfile(char *file, int *size) { FILE *fp; long lSize; char *buffer; fp = fopen ( file , "rb" ); if( !fp ) perror(file),exit(1); fseek( fp , 0L , SEEK_END); lSize = ftell( fp ); rewind( fp ); /* allocate memory for entire content */ buffer = calloc( 1, lSize+1 ); if( !buffer ) fclose(fp),fputs("memory alloc fails",stderr),exit(1); /* copy the file into the buffer */ if( 1!=fread( buffer , lSize, 1 , fp) ) fclose(fp),free(buffer),fputs("entire read fails",stderr),exit(1); /* do your work here, buffer is a string contains the whole text */ size = (int *)lSize; fclose(fp); return buffer; } 

Recibo una advertencia: advertencia: la asignación convierte el puntero de un entero sin un molde. Esto está en el size = (int)lSize; línea size = (int)lSize; . Si ejecuto la aplicación, segfaults.

Actualización: el código anterior funciona ahora. Localicé el segfault, y publiqué otra pregunta. Gracias por la ayuda.

 FILE *fp; long lSize; char *buffer; fp = fopen ( "blah.txt" , "rb" ); if( !fp ) perror("blah.txt"),exit(1); fseek( fp , 0L , SEEK_END); lSize = ftell( fp ); rewind( fp ); /* allocate memory for entire content */ buffer = calloc( 1, lSize+1 ); if( !buffer ) fclose(fp),fputs("memory alloc fails",stderr),exit(1); /* copy the file into the buffer */ if( 1!=fread( buffer , lSize, 1 , fp) ) fclose(fp),free(buffer),fputs("entire read fails",stderr),exit(1); /* do your work here, buffer is a string contains the whole text */ fclose(fp); free(buffer); 

Una solución en forma de un progtwig completo que responde a la pregunta y la demuestra. Es un poco más explícito que otras respuestas y, por lo tanto, más fácil de entender para los menos experimentados en C (en mi humilde opinión).

 #include  #include  #include  /* * 'slurp' reads the file identified by 'path' into a character buffer * pointed at by 'buf', optionally adding a terminating NUL if * 'add_nul' is true. On success, the size of the file is returned; on * failure, -1 is returned and ERRNO is set by the underlying system * or library call that failed. * * WARNING: 'slurp' malloc()s memory to '*buf' which must be freed by * the caller. */ long slurp(char const* path, char **buf, bool add_nul) { FILE *fp; size_t fsz; long off_end; int rc; /* Open the file */ fp = fopen(path, "rb"); if( NULL == fp ) { return -1L; } /* Seek to the end of the file */ rc = fseek(fp, 0L, SEEK_END); if( 0 != rc ) { return -1L; } /* Byte offset to the end of the file (size) */ if( 0 > (off_end = ftell(fp)) ) { return -1L; } fsz = (size_t)off_end; /* Allocate a buffer to hold the whole file */ *buf = malloc( fsz+(int)add_nul ); if( NULL == *buf ) { return -1L; } /* Rewind file pointer to start of file */ rewind(fp); /* Slurp file into buffer */ if( fsz != fread(*buf, 1, fsz, fp) ) { free(*buf); return -1L; } /* Close the file */ if( EOF == fclose(fp) ) { free(*buf); return -1L; } if( add_nul ) { /* Make sure the buffer is NUL-terminated, just in case */ buf[fsz] = '\0'; } /* Return the file size */ return (long)fsz; } /* * Usage message for demo (in main(), below) */ void usage(void) { fputs("USAGE: ./slurp \n", stderr); exit(1); } /* * Demonstrates a call to 'slurp'. */ int main(int argc, char *argv[]) { long file_size; char *buf; /* Make sure there is at least one command-line argument */ if( argc < 2 ) { usage(); } /* Try the first command-line argument as a file name */ file_size = slurp(argv[1], &buf, false); /* Bail if we get a negative file size back from slurp() */ if( file_size < 0L ) { perror("File read failed"); usage(); } /* Write to stdout whatever slurp() read in */ (void)fwrite(buf, 1, file_size, stdout); /* Remember to free() memory allocated by slurp() */ free( buf ); return 0; } 

Como utilicé slurp() esperando que funcionara, unos días después descubrí que … no es así.

Entonces, para las personas que están ansiosas por copiar / pegar una solución para “obtener el contenido de un ARCHIVO en un char *”, aquí hay algo que puede usar.

 char* load_file(char const* path) { char* buffer = 0; long length; FILE * f = fopen (path, "rb"); //was "rb" if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = (char*)malloc ((length+1)*sizeof(char)); if (buffer) { fread (buffer, sizeof(char), length, f); } fclose (f); } buffer[length] = '\0'; // for (int i = 0; i < length; i++) { // printf("buffer[%d] == %c\n", i, buffer[i]); // } //printf("buffer = %s\n", buffer); return buffer; } 

fgets () es una función C que se puede usar para lograr esto.

Editar: También puedes considerar usar fread ().