Estoy aprendiendo a escribir y leer archivos en C, y escribí un texto usando este código
FILE *f = fopen("testingText.txt", "w"); char *text = "This is text1..."; fwrite(text, sizeof(char), strlen(text), f ); fclose(f);y cuando leo el contenido de este archivo y lo imprimo usando este código
FILE *f = fopen("testingText.txt", "r"); fseek(f, 0, SEEK_END); unsigned int size = ftell(f); fseek(f , 0, SEEK_SET); char *content = (char *)malloc(size); fread(content, sizeof(char), size, f); printf("File content is...\n%s", content); free(content); fclose(f);da el resultado con cosas raras como estas
El contenido del archivo es... Esto es text1...Path=C:* ┬#æ╩eò *
y cuando vuelvo a ejecutar el código, da diferentes cosas extrañas.
No hay un terminador nulo en el archivo, por lo que deberá agregarlo manualmente antes de imprimir lo que ha leído del archivo.
Ejemplo:
char *content = malloc(size + 1); // +1 for the null terminator size_t chars_read = fread(content, 1, size, f); // store the returned value content[chars_read] = '\0'; // add null terminator printf("File content is...\n%s\n", content); // now ok to printLa siguiente línea es incorrecta:
printf("File content is...\n%s", content); El uso de printf con el especificador de formato de conversión %s requiere una cadena terminada en nulo. Sin embargo, su cadena no termina en nulo.
Para imprimir una secuencia de caracteres que no termine en nulo, puede escribir lo siguiente en su lugar:
printf( "File content is...\n%.*s", (int)size, content );O puede agregar un carácter nulo de terminación manualmente, con la siguiente línea:
content[size] = '\0'; Sin embargo, esto escribirá en el content del búfer de memoria fuera de los límites, porque no asignó ningún espacio para el carácter de terminación nulo. Por lo tanto, debe asignar un byte adicional en la llamada a la función malloc .
Otro problema es que usar ftell no es una forma confiable de determinar la longitud del archivo. El estándar ISO C no garantiza que esto funcione.
Por ejemplo, en Microsoft Windows, esto le dará la longitud del archivo en modo binario (incluso cuando el archivo se abre en modo de texto). Sin embargo, la longitud del archivo en modo texto es diferente, porque los finales de línea \r\n se traducen a \n en Microsoft Windows.
Por lo tanto, si desea leer el contenido de un archivo de texto de longitud desconocida, probablemente sería mejor leer una línea a la vez en un bucle, utilizando la función fgets :
#include <stdio.h> #include <stdlib.h> int main( void ) { FILE *fp; char line[100]; //attempt to open file fp = fopen( "testingText.txt", "r" ); //verify that file is open if ( fp == NULL ) { fprintf( stderr, "error opening file!\n" ); exit( EXIT_FAILURE ); } printf( "File content is...\n" ); //print one line per loop iteration while ( fgets( line, sizeof line, fp ) != NULL ) { //the following code will work even if "fgets" only //reads a partial line, due to the input buffer not //being large enough //print the line to standard output fputs( line, stdout ); } //cleanup fclose( fp ); }