2010-02-27 6 views
8

Ce que je dois faire est d'utiliser la fonction de lecture de unistd.h pour lire un fichier ligne par ligne. J'ai ce au moment:unistd.h read() function: Comment lire un fichier ligne par ligne?

n = read(fd, str, size); 

Cependant, ce lit à la fin du fichier, ou jusqu'à numéro de taille d'octets. Y a-t-il un moyen pour que je puisse le faire lire une ligne à la fois, en m'arrêtant à une nouvelle ligne? Les lignes ont toutes une longueur variable.

Je suis autorisé que ces deux fichiers d'en-tête:.

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

Le but de l'exercice est de lire dans un fichier ligne par ligne et sortie chaque ligne comme il est lu en gros, pour imiter les fgets() et fonctions fputs().

+0

Vous devez utiliser 'write()' pour imiter 'fputs()' - vous ne pouvez pas faire cela avec read :) –

Répondre

8

Vous pouvez lire caractère par caractère dans un tampon et vérifier les symboles de saut de ligne (\r\n pour Windows et \n pour les systèmes Unix).

0

C'est une bonne question, mais ne permettre que la fonction de lecture n'aide pas! : P

Boucle lire les appels pour obtenir un nombre fixe d'octets, et rechercher le caractère '\ n', puis retourner une partie de la chaîne (jusqu'à '\ n'), et stocke le reste (sauf '\ n ') pour préfixer au bloc de fichier de caractères suivant.

Utiliser la mémoire dynamique.

Plus la taille de la mémoire tampon est importante, moins les appels de lecture sont utilisés (ce qui est un appel système, donc pas bon marché mais de nos jours il y a des noyaux préemptifs).

...

Ou simplement fixer une longueur maximale de la ligne, et utiliser fgets, si vous devez être rapide ...

0

Si vous ouvrez le fichier en mode texte puis Windows « \ r \ n "sera traduit silencieusement en" \ n "lors de la lecture du fichier.

Si vous êtes sous Unix, vous pouvez utiliser la fonction non standard gcc 'getline()'.


getline() La fonction est standard dans POSIX 2008.

+3

L'OP veut lire à partir d'un descripteur de fichier, pas d'un flux FICHIER. getline() lit à partir d'un flux FILE et requiert , ce qui n'est pas autorisé. – SzG

0

bien, il sera lu ligne par ligne à partir d'un terminal.

Certains choix que vous avez sont:

  • Ecrire une fonction qui utilise la lecture quand il est à court de données, mais ne retourne une ligne à la fois à l'appelant
  • Utilisez la fonction dans la bibliothèque qui ne exactement cela: fgets().
  • Ne lisez qu'un seul octet à la fois, donc n'allez pas trop loin.
1

Malheureusement, la fonction de lecture n'est pas vraiment adaptée à ce type d'entrée.En supposant que ce soit une sorte d'exigence artificielle d'interview/devoirs/exercices, vous pouvez essayer de simuler l'entrée par ligne en lisant le fichier en morceaux et en le découpant sur le caractère de nouvelle ligne, en maintenant l'état entre les appels. Vous pouvez vous en sortir avec un indicateur de position statique si vous documentez soigneusement l'utilisation de la fonction.

4

Vous aurez besoin de créer un tampon deux fois plus long que votre ligne la plus longue que vous supporterez, et vous aurez besoin de garder une trace de votre état de tampon.

Fondamentalement, chaque fois que vous êtes appelé pour une nouvelle ligne, vous balayez à partir de votre position de tampon actuelle à la recherche d'un marqueur de fin de ligne. Si vous en trouvez un, bon, c'est votre ligne. Mettez à jour vos pointeurs de tampon et renvoyez. Si vous atteignez votre longueur maximale, vous retournez une ligne tronquée et changez d'état pour la rejeter. La prochaine fois que vous êtes appelé, vous devez ignorer la fin de la ligne suivante, puis entrer votre état de lecture normal. Si vous atteignez la fin de ce que vous avez lu, alors vous devez lire dans un autre caractères maxline, en l'enveloppant au début du tampon si vous frappez le bas (par exemple, vous devrez peut-être faire deux appels de lecture), puis continuez la numérisation. Tout ce qui précède suppose que vous pouvez définir une longueur de ligne maximale. Si vous ne pouvez pas alors vous devez travailler avec de la mémoire dynamique et vous inquiéter de ce qui se passe si un tampon malloc échoue. En outre, vous devrez toujours vérifier les résultats de la lecture dans le cas où vous avez frappé la fin du fichier tout en lisant dans votre tampon.

1

Si vous avez besoin de lire exactement 1 ligne (sans dépasser) en utilisant read(), la seule façon généralement applicable est de lire 1 octet à la fois et de faire une boucle jusqu'à ce que vous obteniez un octet de nouvelle ligne. Cependant, si votre descripteur de fichier fait référence à un terminal et qu'il est dans le mode par défaut (canonique), read attendra un retour à la ligne et retournera moins que la taille demandée dès qu'une ligne est disponible. Il peut cependant renvoyer plus d'une ligne, si les données arrivent très rapidement, ou moins de 1 ligne si le tampon de votre programme ou le tampon du terminal interne est plus court que la longueur de la ligne. À moins que vous n'ayez vraiment besoin d'éviter le surpassez (ce qui est parfois important, si vous voulez qu'un autre processus/programme hérite du descripteur de fichier et puisse reprendre la lecture là où vous l'avez laissé), je suggère d'utiliser les fonctions stdio ou votre propre système tampon. L'utilisation de read pour les E/S basées sur une ligne ou octet par octet est très douloureuse et difficile à obtenir.

Questions connexes