¿Cómo leer el contenido de un archivo en una cadena en C?
¿Cuál es la forma más sencilla (menos propensa a errores, menos líneas de código, como quiera interpretarlo) de abrir un archivo en C y leer su contenido en una cadena (char*, char[], lo que sea)?
Tiendo a cargar todo el búfer como un fragmento de memoria sin procesar en la memoria y hacer el análisis por mi cuenta. De esa manera tengo un mejor control sobre lo que hace la biblioteca estándar en múltiples plataformas.
Este es un trozo que uso para esto. También es posible que desees comprobar los códigos de error de fseek, ftell y fread. (omitido para mayor claridad).
char * buffer = 0;
long length;
FILE * f = fopen (filename, "rb");
if (f)
{
fseek (f, 0, SEEK_END);
length = ftell (f);
fseek (f, 0, SEEK_SET);
buffer = malloc (length);
if (buffer)
{
fread (buffer, 1, length, f);
}
fclose (f);
}
if (buffer)
{
// start to process your data / extract strings here...
}
Otra solución, lamentablemente altamente dependiente del sistema operativo, es la asignación de memoria del archivo. Los beneficios generalmente incluyen el rendimiento de la lectura y un uso reducido de la memoria, ya que la vista de las aplicaciones y el caché de archivos del sistema operativo pueden compartir la memoria física.
El código POSIX se vería así:
int fd = open("filename", O_RDONLY);
int len = lseek(fd, 0, SEEK_END);
void *data = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
Windows, por otro lado, es un poco más complicado y, lamentablemente, no tengo un compilador delante para probar, pero la funcionalidad la proporcionan CreateFileMapping()
y MapViewOfFile()
.
Si "leer su contenido en una cadena" significa que el archivo no contiene caracteres con código 0, también puede usar la función getdelim(), que acepta un bloque de memoria y lo reasigna si es necesario, o simplemente asigna todo el búfer para usted y lee el archivo hasta que encuentra un delimitador especificado o el final del archivo. Simplemente pase '\0' como delimitador para leer el archivo completo.
Esta función está disponible en la biblioteca GNU C, http://www.gnu.org/software/libc/manual/html_mono/libc.html#index-getdelim-994
El código de muestra puede parecer tan simple como
char* buffer = NULL;
size_t len;
ssize_t bytes_read = getdelim( &buffer, &len, '\0', fp);
if ( bytes_read != -1) {
/* Success, now the entire file is in the buffer */