2010-02-27 20 views
8

Lo que necesito hacer es usar la función de lectura de unistd.h para leer un archivo línea por línea. Tengo esto en la actualidadunistd.h función de lectura(): ¿cómo leer un archivo línea por línea?

n = read(fd, str, size); 

Sin embargo, esto se lee al final del archivo, o hasta el número de bytes de tamaño. ¿Hay alguna manera de que pueda leer una línea a la vez, deteniéndose en una nueva línea? Las líneas son todas de longitud variable.

me permite solamente estos dos archivos de cabecera:.

#include <unistd.h> 
#include <fcntl.h> 

El objetivo del ejercicio es leer en un archivo línea por línea, y salida de cada línea como se lee en el fondo, para imitar el fgets() y funciones fputs().

+0

Tendrá que utilizar 'write()' para imitar 'fputs()' - no puede hacer eso con read :) –

Respuesta

8

Puede leer carácter por carácter en un búfer y comprobar si hay símbolos de salto de línea (\r\n para Windows y \n para sistemas Unix).

0

Esta es una buena pregunta, pero permitir solo la función de lectura no ayuda. : P

Llamadas de lectura en bucle para obtener un número fijo de bytes, buscar el carácter '\ n', devolver una parte de la cadena (hasta '\ n') y almacenar el resto (excepto '\ n ') para anteponer al siguiente fragmento de archivo de caracteres.

Usar memoria dinámica.

mayor sea el tamaño de la memoria intermedia, menos Lee llamadas usadas (que es una llamada al sistema, por lo que no es barato, pero hoy en día hay núcleos de preferencia).

...

O simplemente fijar una longitud máxima de línea, y utilizar fgets, si tiene que ser rápido ...

0

Si abre el archivo en modo de texto a continuación, Windows "\ r \ n "se traducirá silenciosamente a" \ n "a medida que se lea el archivo.

Si está en Unix puede usar la función no estándar gcc 'getline()'.


La función getline() es estándar POSIX en 2008.

+3

El OP quiere leer de un descriptor de archivo, no de una secuencia FILE. getline() lee desde una secuencia FILE y requiere , lo cual no está permitido. – SzG

0

Bueno, se lee línea a línea, desde un terminal.

Algunas opciones que tiene son:

  • escribir una función que utiliza leer cuando se queda sin datos, pero sólo devuelve una línea a la vez a la persona que llama
  • Uso de la función en la biblioteca que hace exactamente eso: fgets().
  • Lea solo un byte a la vez, para que no vaya demasiado lejos.
1

Por desgracia, la función de lectura no es muy adecuado para este tipo de entrada.Suponiendo que esto es algún tipo de requisito artificial de la entrevista/tarea/ejercicio, puede intentar simular la entrada basada en línea leyendo el archivo en trozos y dividiéndolo en el carácter de nueva línea, manteniendo el estado de alguna manera entre las llamadas. Puede escaparse con un indicador de posición estático si documenta cuidadosamente el uso de la función.

4

Querrá crear un búfer que sea el doble de la longitud de la línea más larga que admitirá, y deberá realizar un seguimiento del estado del búfer.

Básicamente, cada vez que te piden una nueva línea, escanearás desde tu posición de búfer actual en busca de un marcador de fin de línea. Si encuentras uno, bien, esa es tu línea. Actualiza tus punteros de búfer y regresa.

Si llega a su longitud máxima, devuelve una línea truncada y cambia su estado para descartarla. La próxima vez que lo llames, debes descartarlo hasta el siguiente final de línea y luego ingresar tu estado de lectura normal.

Si tocas el final de lo que has leído, entonces necesitas leer en otros caracteres maxline, envolviendo el inicio del búfer si tocas el final (es decir, es posible que tengas que hacer dos llamadas de lectura) y luego continúe escaneando.

Todo lo anterior supone que puede establecer una longitud de línea máxima. Si no puede, debe trabajar con memoria dinámica y preocuparse por lo que sucede si falla un búfer malloc. Además, deberá verificar siempre los resultados de la lectura en caso de que haya tocado el final del archivo mientras leía en el búfer.

1

Si necesita leer exactamente 1 línea (y no sobrepasar) usando read(), la única forma generalmente aplicable de hacerlo es leyendo 1 byte a la vez y bucles hasta obtener un byte de nueva línea. Sin embargo, si su descriptor de archivo se refiere a un terminal y está en el modo predeterminado (canónico), leer esperará una nueva línea y devolverá menos del tamaño solicitado tan pronto como haya una línea disponible. Sin embargo, puede devolver más de una línea, si los datos llegan muy rápidamente, o menos de 1 línea si el buffer de su programa o el buffer del terminal interno es más corto que la longitud de la línea.

A menos que realmente deba evitar el paso en exceso (que a veces es importante, si desea que otro proceso/programa herede el descriptor del archivo y pueda continuar la lectura donde lo dejó), le sugiero que use stdio funciones o propio sistema de almacenamiento en búfer. Usar read para IO basado en línea o byte a byte es muy doloroso y difícil de resolver.

Cuestiones relacionadas