Vous ne pouvez pas accéder directement à une ligne donnée d'un fichier texte (à moins que un caractère Unicode peut prendre un nombre variable d'octets, de 1 à 6, et dans la plupart des cas, les lignes ont des longueurs différentes (différentes d'une ligne à l'autre). Donc, vous ne pouvez pas utiliser fseek (parce que vous ne savez pas à l'avance le décalage de fichier).
Cependant (au moins sur les systèmes Linux), les lignes se terminent par \n
(le caractère de retour à la ligne). Ainsi, vous pouvez lire octet par octet et les compter:
int c= EOF;
int linecount=1;
while ((c=fgetc(file)) != EOF) {
if (c=='\n')
linecount++;
}
Vous n'avez alors pas besoin de stocker la ligne entière.
vous pouvez donc atteindre la ligne n ° 45 de cette façon (en utilisant while ((c=fgetc(file)) != EOF) && linecount<45)
...) et seulement lire ensuite des lignes entières avec fgets
ou mieux encore getline(3) sur les systèmes POSIX (voir this exemple). Notez que l'implémentation de fgets
ou de getline
est susceptible d'être construite au-dessus de fgetc
, ou du moins de partager du code avec elle. Rappelez-vous que <stdio.h>
est tamponné E/S, voir setvbuf(3) et les fonctions connexes.
Une autre façon serait de lire le fichier en deux passes. Un premier passage enregistre le décalage (en utilisant ftell(3) ...) de chaque début de ligne dans une structure de données efficace (un vecteur, une table de hachage, un arbre ...). Un second passage utilise cette structure de données pour récupérer le décalage (du début de ligne), puis utilise fseek(3) (en utilisant ce décalage).
Une troisième voie, spécifique Posix, serait de mémoire la carte en utilisant le fichier mmap(2) dans votre virtual address space (cela fonctionne bien pour les fichiers pas trop énormes, par exemple de moins de quelques giga-octets). Avec des soins (vous pourriez avoir besoin de mmap
une page de fin supplémentaire, pour assurer que les données est mis fin à zéro octet), vous serez alors en mesure d'utiliser strchr(3) avec '\n'
PS. BTW, la notion de lignes (et la marque de fin de ligne) varient d'un OS à l'autre. Sous Linux, la fin de ligne est un caractère \n
. Sur les lignes Windows sont selon la rumeur pour mettre fin à \r\n
, etc ...
Pour les fichiers ordinaires, la seule façon de faire mieux est de construire et de maintenir votre propre indice de numéros de ligne et décalages 'fseek'. (Ceci est simple, mais un peu de travail.) –