txt que programacion programa por manejo linea libreria leer lectura lea guardar escritura datos binarios ats archivos archivo c getline scanf

que - Pasando por un archivo de texto línea por línea en C



programa en c que lea un archivo txt (4)

Además de las otras respuestas, en una biblioteca de C reciente (compatible con Posix 2008), puede usar getline . Ver esta respuesta (a una pregunta relacionada).

He estado trabajando en un pequeño ejercicio para mi clase CIS y estoy muy confundido por los métodos que C usa para leer un archivo. Todo lo que realmente necesito hacer es leer un archivo línea por línea y usar la información recopilada de cada línea para hacer algunas manipulaciones. Intenté usar el método getline y otros sin suerte. Mi código es actualmente como sigue:

int main(char *argc, char* argv[]){ const char *filename = argv[0]; FILE *file = fopen(filename, "r"); char *line = NULL; while(!feof(file)){ sscanf(line, filename, "%s"); printf("%s/n", line); } return 1; }

Ahora mismo estoy teniendo una falla de seg con el método sscanf y no estoy seguro de por qué. Soy un total de C noob y me pregunto si había algo del panorama general que me faltaba. Gracias


Digamos que está tratando con algún otro delimitador, como una pestaña /t , en lugar de una /n nueva línea.

Un enfoque más general de los delimitadores es el uso de getc() , que capta un personaje a la vez.

Tenga en cuenta que getc() devuelve un int , para que podamos probar la igualdad con EOF .

En segundo lugar, definimos una line[BUFFER_MAX_LENGTH] matriz line[BUFFER_MAX_LENGTH] de tipo char , para almacenar hasta BUFFER_MAX_LENGTH-1 caracteres en la pila (tenemos que guardar ese último carácter para un carácter terminador /0 ).

El uso de una matriz evita la necesidad de usar malloc y free para crear un puntero de carácter de la longitud correcta en el montón.

#define BUFFER_MAX_LENGTH 1024 int main(int argc, char* argv[]) { FILE *file = NULL; char line[BUFFER_MAX_LENGTH]; int tempChar; unsigned int tempCharIdx = 0U; if (argc == 2) file = fopen(argv[1], "r"); else { fprintf(stderr, "error: wrong number of arguments/n" "usage: %s textfile/n", argv[0]); return EXIT_FAILURE; } if (!file) { fprintf(stderr, "error: could not open textfile: %s/n", argv[1]); return EXIT_FAILURE; } /* get a character from the file pointer */ while(tempChar = fgetc(file)) { /* avoid buffer overflow error */ if (tempCharIdx == BUFFER_MAX_LENGTH) { fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH./n"); return EXIT_FAILURE; } /* test character value */ if (tempChar == EOF) { line[tempCharIdx] = ''/0''; fprintf(stdout, "%s/n", line); break; } else if (tempChar == ''/n'') { line[tempCharIdx] = ''/0''; tempCharIdx = 0U; fprintf(stdout, "%s/n", line); continue; } else line[tempCharIdx++] = (char)tempChar; } return EXIT_SUCCESS; }

Si debe usar un char * , entonces puede seguir usando este código, pero strdup() la line[] array, una vez que se llena con el valor de entrada de una línea. Debe free esta cadena duplicada una vez que haya terminado con ella, o obtendrá una pérdida de memoria:

#define BUFFER_MAX_LENGTH 1024 int main(int argc, char* argv[]) { FILE *file = NULL; char line[BUFFER_MAX_LENGTH]; int tempChar; unsigned int tempCharIdx = 0U; char *dynamicLine = NULL; if (argc == 2) file = fopen(argv[1], "r"); else { fprintf(stderr, "error: wrong number of arguments/n" "usage: %s textfile/n", argv[0]); return EXIT_FAILURE; } if (!file) { fprintf(stderr, "error: could not open textfile: %s/n", argv[1]); return EXIT_FAILURE; } while(tempChar = fgetc(file)) { /* avoid buffer overflow error */ if (tempCharIdx == BUFFER_MAX_LENGTH) { fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH./n"); return EXIT_FAILURE; } /* test character value */ if (tempChar == EOF) { line[tempCharIdx] = ''/0''; dynamicLine = strdup(line); fprintf(stdout, "%s/n", dynamicLine); free(dynamicLine); dynamicLine = NULL; break; } else if (tempChar == ''/n'') { line[tempCharIdx] = ''/0''; tempCharIdx = 0U; dynamicLine = strdup(line); fprintf(stdout, "%s/n", dynamicLine); free(dynamicLine); dynamicLine = NULL; continue; } else line[tempCharIdx++] = (char)tempChar; } return EXIT_SUCCESS; }


Para leer una línea de un archivo, debe usar la función fgets : Lee una cadena desde el archivo especificado hasta un carácter de nueva línea o EOF .

El uso de sscanf en su código no funcionaría en absoluto, ya que usa el filename como su cadena de formato para leer desde una line hasta una cadena constante literal %s .

El motivo de SEGV es que escribe en la memoria no asignada apuntada por line .


Tantos problemas en tan pocas líneas. Probablemente me olvide de algunos:

  • argv [0] es el nombre del programa, no el primer argumento;
  • Si quieres leer en una variable, tienes que asignar su memoria.
  • uno nunca realiza un bucle en feof, uno hace un bucle en una función IO hasta que falla, feof sirve para determinar el motivo del fallo,
  • sscanf está ahí para analizar una línea, si desea analizar un archivo, use fscanf,
  • "% s" se detendrá en el primer espacio como formato para la familia? scanf
  • Para leer una línea, la función estándar es fgets,
  • devolviendo 1 del fallo de medios principales

Asi que

#include <stdio.h> int main(int argc, char* argv[]) { char const* const fileName = argv[1]; /* should check that argc > 1 */ FILE* file = fopen(fileName, "r"); /* should check the result */ char line[256]; while (fgets(line, sizeof(line), file)) { /* note that fgets don''t strip the terminating /n, checking its presence would allow to handle lines longer that sizeof(line) */ printf("%s", line); } /* may check feof here to make a difference between eof and io failure -- network timeout for instance */ fclose(file); return 0; }