
hierro
Escribí esta función para leer una línea de un archivo:
const char *readLine(FILE *file) {
if (file == NULL) {
printf("Error: file pointer is null.");
exit(1);
}
int maximumLineLength = 128;
char *lineBuffer = (char *)malloc(sizeof(char) * maximumLineLength);
if (lineBuffer == NULL) {
printf("Error allocating memory for line buffer.");
exit(1);
}
char ch = getc(file);
int count = 0;
while ((ch != '\n') && (ch != EOF)) {
if (count == maximumLineLength) {
maximumLineLength += 128;
lineBuffer = realloc(lineBuffer, maximumLineLength);
if (lineBuffer == NULL) {
printf("Error reallocating space for line buffer.");
exit(1);
}
}
lineBuffer[count] = ch;
count++;
ch = getc(file);
}
lineBuffer[count] = '\0';
char line[count + 1];
strncpy(line, lineBuffer, (count + 1));
free(lineBuffer);
const char *constLine = line;
return constLine;
}
La función lee el archivo correctamente y, al usar printf, veo que la cadena constLine también se leyó correctamente.
Sin embargo, si uso la función, por ejemplo, así:
while (!feof(myFile)) {
const char *line = readLine(myFile);
printf("%s\n", line);
}
printf genera un galimatías. ¿Por qué?

mbaitoff
Si su tarea no es inventar la función de lectura línea por línea, sino simplemente leer el archivo línea por línea, puede usar un fragmento de código típico que involucre el getline()
función (ver la página del manual aquí):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
fp = fopen("/etc/motd", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, fp)) != -1) {
printf("Retrieved line of length %zu:\n", read);
printf("%s", line);
}
fclose(fp);
if (line)
free(line);
exit(EXIT_SUCCESS);
}

Robar
FILE* filePointer;
int bufferLength = 255;
char buffer[bufferLength]; /* not ISO 90 compatible */
filePointer = fopen("file.txt", "r");
while(fgets(buffer, bufferLength, filePointer)) {
printf("%s\n", buffer);
}
fclose(filePointer);

gsamaras
Una completa, fgets()
solución:
#include <stdio.h>
#include <string.h>
#define MAX_LEN 256
int main(void)
{
FILE* fp;
fp = fopen("file.txt", "r");
if (fp == NULL) {
perror("Failed: ");
return 1;
}
char buffer[MAX_LEN];
while (fgets(buffer, MAX_LEN, fp))
{
// Remove trailing newline
buffer[strcspn(buffer, "\n")] = 0;
printf("%s\n", buffer);
}
fclose(fp);
return 0;
}
Producción:
First line of file
Second line of file
Third (and also last) line of file
Recuerde, si desea leer desde la entrada estándar (en lugar de un archivo como en este caso), todo lo que tiene que hacer es pasar stdin
como el tercer parámetro de fgets()
método, así:
while(fgets(buffer, MAX_LEN, stdin))
Apéndice
Eliminar el carácter de nueva línea final de la entrada fgets ()
como detectar un archivo esta abierto o no en c

RevoLab
//open and get the file handle
FILE* fh;
fopen_s(&fh, filename, "r");
//check if file exists
if (fh == NULL){
printf("file does not exists %s", filename);
return 0;
}
//read line by line
const size_t line_size = 300;
char* line = malloc(line_size);
while (fgets(line, line_size, fh) != NULL) {
printf(line);
}
free(line); // dont forget to free heap memory

Gilles ‘SO- deja de ser malvado’
En tus readLine
función, devuelve un puntero a la line
matriz (estrictamente hablando, un puntero a su primer carácter, pero la diferencia es irrelevante aquí). Dado que es una variable automática (es decir, está “en la pila”), la memoria se recupera cuando la función regresa. Ves galimatías porque printf
ha puesto sus propias cosas en la pila.
Debe devolver un búfer asignado dinámicamente desde la función. Ya tienes uno, es lineBuffer
; todo lo que tiene que hacer es truncarlo a la longitud deseada.
lineBuffer[count] = '\0';
realloc(lineBuffer, count + 1);
return lineBuffer;
}
AGREGADO (respuesta a la pregunta de seguimiento en el comentario): readLine
devuelve un puntero a los caracteres que componen la línea. Este puntero es lo que necesita para trabajar con el contenido de la línea. También es lo que debes pasar a free
cuando hayas terminado de usar la memoria tomada por estos personajes. Así es como puede usar el readLine
función:
char *line = readLine(file);
printf("LOG: read a line: %s\n", line);
if (strchr(line, 'a')) { puts("The line contains an a"); }
/* etc. */
free(line);
/* After this point, the memory allocated for the line has been reclaimed.
You can't use the value of `line` again (though you can assign a new value
to the `line` variable if you want). */

Akhil V Suku
Aquí están mis varias horas… Leyendo todo el archivo línea por línea.
char * readline(FILE *fp, char *buffer)
{
int ch;
int i = 0;
size_t buff_len = 0;
buffer = malloc(buff_len + 1);
if (!buffer) return NULL; // Out of memory
while ((ch = fgetc(fp)) != '\n' && ch != EOF)
{
buff_len++;
void *tmp = realloc(buffer, buff_len + 1);
if (tmp == NULL)
{
free(buffer);
return NULL; // Out of memory
}
buffer = tmp;
buffer[i] = (char) ch;
i++;
}
buffer[i] = '\0';
// Detect end
if (ch == EOF && (i == 0 || ferror(fp)))
{
free(buffer);
return NULL;
}
return buffer;
}
void lineByline(FILE * file){
char *s;
while ((s = readline(file, 0)) != NULL)
{
puts(s);
free(s);
printf("\n");
}
}
int main()
{
char *fileName = "input-1.txt";
FILE* file = fopen(fileName, "r");
lineByline(file);
return 0;
}

Escapar de Raku
Usar fgets()
para leer una línea de un identificador de archivo.
Usar
fgets
en vez defgetc
. Estás leyendo carácter por carácter en lugar de línea por línea.– Puñal
17 de marzo de 2017 a las 4:00
Tenga en cuenta que
getline()
es parte de POSIX 2008. Puede haber plataformas similares a POSIX sin él, especialmente si no son compatibles con el resto de POSIX 2008, pero dentro del mundo de los sistemas POSIX,getline()
es bastante portátil en estos días.–Jonathan Leffler
8 mayo 2017 a las 21:20