Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1426 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  déterminer le nombre de lignes d'un fichier texte

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

déterminer le nombre de lignes d'un fichier texte

n°2052661
shaoyin
Posté le 28-01-2011 à 12:17:07  profilanswer
 

Bonjour,
 
je cherche à déterminer le nombre de lignes d'un fichier texte (celui-ci pouvant aller jusqu'à 65000 lignes).
 
Pour l'instant, ma solution consiste à parcourir le fichier en comptant le nombre de caractère '\n', mais je suis perplexe quant à l'implémentation. Voici mon code :
 

Code :
  1. unsigned short cpt = 0; // Décompte du nombre de lignes
  2. std::ifstream ifs ( <fichier> );
  3. if ( ifs.fail() == false ) { // OK le fichier existe
  4.     char buf [ 500 ];
  5.     do {
  6.         ifs.getline ( buf , 500 , '\n' );
  7.         if ( ifs.fail() == false ) {
  8.             ++cpt; // incrémentation du nombre de lignes
  9.         }
  10.     } while ( ifs.eof() == false );
  11. }


Le problème, c'est que je ne connais pas exactement la taille maximum de chaque ligne. Je fixe donc une valeur arbitraire (500) au buffer de lecture en espérant qu'elle suffise dans la plupart des cas.
Si la ligne fait plus de 500 caractères, le "fail bit" est activé. Je sais donc que ma ligne est incomplète et je n'incrémente pas le compteur.
 
Je m'interroge dans le cas où la ligne fait exactement 499 caractères. Que se passe-t-il dans ce cas de figure ?
 
Et indépendamment de mon code, existe-t-il une autre solution plus performante que la mienne ?
 
Merci d'avance !

mood
Publicité
Posté le 28-01-2011 à 12:17:07  profilanswer
 

n°2052700
billgatesa​nonym
Posté le 28-01-2011 à 14:21:25  profilanswer
 

Une autre solution est une lecture en mode binaire et de compter les fins de lignes (avec le petit soucis de savoir ce qu'est une fin de ligne : soit CR+LF pour un fichier DOS/Windows, soit LF pour un fichier Unix ou Mac récent, soir CR pour un fichier Mac antérieur à OS X).

n°2052724
shaoyin
Posté le 28-01-2011 à 15:52:48  profilanswer
 

Effectivement, c'est plus trivial en parcourant le fichier en mode binaire. Disparu, le petit cas tordu...
 
Merci !

n°2052841
spiky31
Alias Nounours
Posté le 29-01-2011 à 00:39:49  profilanswer
 

il suffit de compter le nombre de '\n', car le nombre de '\n' bah c'est le nombre de lignes. A bufferiser quand meme pour optimiser la chose ...
A oui, et si le dernier caractere du fichier est != de '\n' rajouter 1


---------------
Persos D3 :: Yipee-ki-yay motherfucker !!
n°2052853
billgatesa​nonym
Posté le 29-01-2011 à 10:44:47  profilanswer
 

S'il vous plait, spiky31, lisez ce que les autres ont écrit précédemment. Cela peut vous apporter des informations utiles.
 
Par exemple, je disais plus haut, le '\n' que l'on appelle aussi Line Feed ou par ses intiales LF n'est pas forcément présent dans le fichier. On peut avoir seulement des '\r' que l'on appelle aussi Carriage Return ou par ses initiales CR.
 
Et j'avais même oublié un autre cas, qui devient de plus en plus courant qui est celui des fichiers Unicode. Alors, on a deux octets par caractères au lieu d'un seul. Il faut donc tester les doubles octets : 0x00 0x0A, 0x00 0x0D, 0x20 0x28, et 0x20 0x29. Par exemple, dans le cas de l'Unicode, si on ne testait que 0x0A, sans tester 0x00 avant, alors on risquerait de tomber sur un caractère qui ne serait pas un caractère de fin de ligne. On aurait un faux positif.
 
Il y a aussi les cas des variantes de l'Unicode que sont l'UTF8 et de l'UTF16.
 
Sans parler de l'EBCDIC où le LF est codé par 0x15.
 
Bref, cela peut paraître simple, mais cela ne l'est pas tant que cela, surtout si on ne sait pas au début quel type de fichier on va traiter.
 
Voir les articles http://fr.wikipedia.org/wiki/Fin_de_ligne , et sa version en anglaise http://en.wikipedia.org/wiki/Newline , plus complète, qui donne même des cas que je n'ai pas évoqués.

n°2052931
spiky31
Alias Nounours
Posté le 29-01-2011 à 20:33:33  profilanswer
 

J'essayais simplement de résoudre son probleme de taille maximum de ligne, qui en fait n'en est pas un.

shaoyin a écrit :

Le problème, c'est que je ne connais pas exactement la taille maximum de chaque ligne.


Maintenant, ce que tu dis est vrai et meme si le cas de '\r' est facile a prendre en compte, le reste l'est beaucoup moins, c'est clair.
Je n'ai d'ailleurs pas la moindre idée de comment traiter le cas de l'unicode, car même si on parcour le fichier en mode binaire, comment savoir quel encodage a été utilisé ?


---------------
Persos D3 :: Yipee-ki-yay motherfucker !!
n°2052954
in_your_ph​ion
Posté le 30-01-2011 à 00:15:44  profilanswer
 
n°2052959
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 30-01-2011 à 01:55:58  profilanswer
 


Catégorie: Programmation

 

Sinon pour détecter l'encodage, lis ce topic: http://www.developpez.net/forums/d [...] ier-texte/

 

Visiblement il n'y a pas de méthode fiable à 100%

Message cité 1 fois
Message édité par WiiDS le 30-01-2011 à 02:15:59

---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
n°2052966
Joel F
Real men use unique_ptr
Posté le 30-01-2011 à 09:33:08  profilanswer
 

.fail() et .eif() ne font pas ce que vous pensez. Quand elles retournent false, c'est deja trop tard.
 
getline renvoit un bool pour indiquer que la lecture a ete faite correctment.
Je vois pas l'interet de se prendre le groin sur le comptage des /r/n

n°2053137
shaoyin
Posté le 31-01-2011 à 09:44:45  profilanswer
 

Dans mon cas, pas de souci, chaque caractère est codé sur un octet, mais en effet, l'encodage est à prendre en compte.
 
Je me demande du coup si la solution avec "getline" ne permet pas de s'affranchir de la question de l'encodage ? La doc ne dit rien dessus, mais est-ce que cette fonction arrive à différencier les types de fin de ligne, ou bien ne connait-elle que le caractère de fin de ligne du système où elle est utilisée ?
 
La solution consistant à faire un appel 'system ("wc -l" )' permet effectivement de ne pas se prendre la tête, mais ce n'est clairement pas la solution la plus performante...
 
@ Joel F : ta remarque sur les fonctions eof et fail m'intrigue... Tu penses que j'utilise mal ces fonctions ?

mood
Publicité
Posté le 31-01-2011 à 09:44:45  profilanswer
 

n°2053735
in_your_ph​ion
Posté le 02-02-2011 à 15:36:25  profilanswer
 

WiiDS a écrit :


Catégorie: Programmation


 
ben programmer c'est aussi ne pas réinventer la roue tout le temps .... Si ce n'est pas un devoir d'école, il y a surement des solutions qui existent déjà (wc, sed, etc) qu'il pourrait (ré)utiliser.
 
 

n°2053751
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 02-02-2011 à 16:03:16  profilanswer
 

in_your_phion a écrit :


 
ben programmer c'est aussi ne pas réinventer la roue tout le temps .... Si ce n'est pas un devoir d'école, il y a surement des solutions qui existent déjà (wc, sed, etc) qu'il pourrait (ré)utiliser.
 
 


Certes, tu as parfaitement raison sur le principe, mais il ne faut pas oublier que l'auteur cherche surement à satisfaire sa curiosité personnelle ou simplement effectivement faire un exercice d'école. :jap:


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
n°2053755
shaoyin
Posté le 02-02-2011 à 16:30:11  profilanswer
 

Ce n'est pas un exercice d'école et ce n'est pas non plus pour satisfaire ma curiosité personnelle.
 
Je suis d'accord sur le fait que Linux fournit plein d'outils géniaux en ligne de commande qui font très bien le boulot, mais je ne veux pas que mon programme soit une succession d'appels à "system" ou "exec". Professionnellement, ca fait pas sérieux.
 
Mon programme est en C++, pas en script shell !

n°2053788
WiiDS
20 titres en GC, 0 abandon, 0 DQ
Posté le 02-02-2011 à 17:26:12  profilanswer
 

shaoyin a écrit :

Ce n'est pas un exercice d'école et ce n'est pas non plus pour satisfaire ma curiosité personnelle.
 
Je suis d'accord sur le fait que Linux fournit plein d'outils géniaux en ligne de commande qui font très bien le boulot, mais je ne veux pas que mon programme soit une succession d'appels à "system" ou "exec". Professionnellement, ca fait pas sérieux.
 
Mon programme est en C++, pas en script shell !


... C'est surtout que un appel à wc -l, niveau portabilité c'est 0, byebye Windows et les systèmes Unix qui n'auraient pas wc :D


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  déterminer le nombre de lignes d'un fichier texte

 

Sujets relatifs
[Batch] Script de comptage du nombre d'occurrences dans un fichierBash - curl - Upload fichier via http
[PHP]Envoyer une fichier à un utilisateur sans lui donner l'adresse[PHP] fournir un fichier hors document root
[résolu] texte pas affiché après code JavaScript de sous-titrageComment appliquer un style de police à du texte contenu dans scriptphp
Zip un fichier en code vbaAjout de lignes dans une table
fichier binaire socket c 
Plus de sujets relatifs à : déterminer le nombre de lignes d'un fichier texte


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR