Compter les lettres d'un fichier texte

Résolu
3xplo Messages postés 10 Date d'inscription mercredi 13 décembre 2006 Statut Membre Dernière intervention 8 juillet 2007 - 3 juil. 2007 à 18:04
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 11 juil. 2007 à 00:33
Bonjour,

j'ai un exercice dans lequel je dois créer un programme qui analyse un
fichier texte pour compter le nombre de "a", de "b", de "c" ..., de "z".

Le résultat doit s'afficher dans une zone de liste, chaque ligne de la
zone doit contenir une lettre et son nombre d'apparition dans le
fichier.


Donc tout ce qui est création graphique du programme jusqu'à l'appel du
fichier texte ça ne pose pas de problème, mais là je bloque pour
compter le nombre de lettre et pour l'affichage dans la zone de texte.


Si vous pouviez m'aider , me donner des conseils svp ça serai sympa car là c'est la panne sèche.

22 réponses

cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
3 juil. 2007 à 20:44
Salut
Si on utilise la lettre recherchée comme borne dans un Split, on obtiendra un tableau de n+1 éléments, donc penser à retirer 1 du UBound
Que fais un Split avec les 'a' avec accent ? = problème supplémentaire
La solution de RenField semble plus adaptée.
- Dimensionner un tableau de Byte en dynamique, genre  Dim aTableau() As Byte
- Lire le fichier en binaire, genre  Open "C:\Mon fichier.txt" For Binary As #1
   puis un redimensionnement du tableau avec la longueur du fichier :
   Redim aTableau(LOF(1) - 1)   ' Le -1 car les tableaux commencent à l'index 0)
   puis la lecture   Get #1,, aTableau
   puis fermeture   Close #1
   Dans aTableau, tu auras les codes ASCII de chaque lettre du texte
- Préparer un tableau des scores pour chaque lettre :  Dim Score(1 To 26) As Long
- Parcourrir le tableau avec une boucle For-Next de 0 à UBound(aTableau)
- Tester chaque lettre dont les codes ASCII vont de 65 à 90 (65+26) pour les majuscules et 97 à 122 pour les minuscules :
   If (aTableau(r) >= 65 And aTableau(r) <= 90) Then
         ' Lettres standard de 'A' à 'Z'
         Score(aTableau(r) - 65 + 1) = Score(aTableau(r) - 65 + 1)
   ElseIf  aTableau(r) >= 97 And aTableau(r) <= 122 Then
         ' Lettres standard de 'a' à 'z'
         Score(aTableau(r) - 97 + 1) = Score(aTableau(r) - 97 + 1)
   Else
         ' Traiter ici les lettres avec accents ...
   End If

Tu récupèreras ainsi le nombre de A dans Score(1) et le nombre de Z dans Score(26)
Il y a surement d'autres méthodes ...

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés
3
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 juil. 2007 à 20:54
vu que le sujet semble intéresser...

voilà le code qui reprend les étapes que j'ai mentionnées plus tôt :

Private Sub Form_Load()
Dim xnCompteurs(25)
Dim xbData() As Byte
Dim iFile As Integer
Dim i As Long
Dim nCar As Long
   iFile = FreeFile
   Open "c:\hijackthis.log" For Binary Access Read As #iFile
   ReDim xbData(LOF(iFile))
   Get #iFile, , xbData
   Close #iFile
   
   For i = 0 To UBound(xbData)
       nCar = xbData(i)
       Select Case nCar
           Case 65 To 90
               xnCompteurs(nCar - 65) = xnCompteurs(nCar - 65) + 1
           Case 97 To 122
               xnCompteurs(nCar - 97) = xnCompteurs(nCar - 97) + 1
       End Select
   Next i
   
   '# Ensuite, libre a toi d'en faire ce que tu veux :
   For i = 0 To 25
       nCar = xnCompteurs(i)
       If nCar Then
           Debug.Print ChrW(65 + i) & " : " nCar & " occurrence(s)"
       End If
   Next i
   
   Unload Me
End Sub , ----
By Renfield

Renfield
Admin CodeS-SourceS- MVP Visual Basic
3
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 juil. 2007 à 18:23
places le fichier dans un tableau de byte

parcoures ton tableau, a ala recherche du code ascii de tes lettre ciblées
incremente des compteurs placés dans un tableau de 26 elements...
0
zavier666 Messages postés 266 Date d'inscription mardi 7 septembre 2004 Statut Membre Dernière intervention 30 avril 2009 1
3 juil. 2007 à 18:25
Solution bricole:


=> charge le texte du fichier dans une variable de type string

=> fait un split sur la lettre qui t'interresse

=> fait un Ubound sur le tableau créé


tu obtiens ainsi le nombre d'occurence de la lettre


slts!


_________________________________________

Toujours + de VB et d'API => APi @ la Loupe

http://apialaloupe.free.fr
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 juil. 2007 à 20:24
oulà, 26 Split , plutot couteux...

mais ca fonctionne, le pbm n'est pas là :p

Renfield
Admin CodeS-SourceS- MVP Visual Basic
0
cs_Exploreur Messages postés 4821 Date d'inscription lundi 11 novembre 2002 Statut Membre Dernière intervention 15 novembre 2016 15
3 juil. 2007 à 20:39
Salut,

J'ai exactement ce qu'il te faut...Regarde ICI, tu devras toute fois retoucher un peu le code, mais la base y est...

A+
Exploreur

 Linux a un noyau, Windows un pépin

 
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
3 juil. 2007 à 20:54
La méthode de Renfield est sans aucun doute la mieux adaptée à ce genre de problème.
Car toutes les autres entrainent un foule de traitements,
y compris celle qui consisterait à "réduire" au fur et à mesure la longueur de la chaîne à examiner, en la parcourant avec Mid et en supprimant, chaque fois, le caractère déjà compté.
Non .. vraiment : pas mieux que ce que Renfield a dit
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 juil. 2007 à 20:55
bon, ben Jack avait dejà fait le boulot ^^

Renfield
Admin CodeS-SourceS- MVP Visual Basic
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
3 juil. 2007 à 21:52
Reste une idée à la....

1) je lis tout le fichier dans une variable toto
2) je l'épure (par replace) des caractères 10 et 13
3) j'en prends la longueur titi = len(toto)
4) je lis le 1er caractère premiercar et l'innscris en colonne 0 d'une listview
5) je supprime (par replace) ce caractère de la chaine toto et mesure la longueur de toto et inscris en colonne 1 de la listview la différence entre len(toto) et titi puis donne à titi la valeur de len(toto)
6) je reprends en 4)

et continue ainsi jusqu'à plus soif (c'est pas demain la veille en ce qui me concerne !...)
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 juil. 2007 à 21:56
tous ces Replace (+/- 28) a un coup => réallocation de la chaine en mémoire

Renfield
Admin CodeS-SourceS- MVP Visual Basic
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
3 juil. 2007 à 22:03
Cà, c'est sur...
Mais il fallait bien trouver un truc à la .... pour finir ma soiirée, non ?

PS : je n'utilise personnellement jamais ni le Replace ni le Split.... (et sais pourquoi...)
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 juil. 2007 à 22:07
*coût

on peu s'en servir, si, faut pas dire...
mais faut faire gaffe à là ou on le met... comme les Variant, faut pas cracher dessus, faut les utiliser avec parcimonie...

faut surtout, je pense, être conscient (to be aware, pour parler comme un certain JC Van Damme)

être conscient de ce qui se passe en coulisses, et choisir les algorithmes en conséquence.
je ne dit pas cela spécialement pour toi mon ami, mais pour ceux qui viendrait a lire ces quelques lignes...

ici, le probleme etait clair et simple : on comptabilise des caractères... pas besoin donc de manipuler des String :p

Renfield
Admin CodeS-SourceS- MVP Visual Basic
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 juil. 2007 à 22:13
Je répondais plus tôt sur un autre post...

le gars lisais un fichier de 50 Mo via Line Input

c'est de l'inconscience... VB va lire la chose caractère par caractère (ou plus certainement par un buffer interne, qui sera scanné par la suite)

surtout que.... ces lignes avaient une taille fixe, et connue.
Un simple calcul pouvait lui permettre de récupérer le strict nécessaire...

comme quoi, faire un code qui fonctionne n'est pas la panacée... et avant de dire que VB est lent, remettre en cause le code qu'on lui demande de traiter ^^

Renfield
Admin CodeS-SourceS- MVP Visual Basic
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
3 juil. 2007 à 22:19
Renfileld > un tableau de 256 évitera tous les 'If' ou 'Case' durant la lecture, on affiche ensuite la partie que l'on veut.
Sera nettement plus rapide sur un gros fichier.

ciao...
BruNews, MVP VC++
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
3 juil. 2007 à 22:26
Je vais mettre tout le monde d'accord...
Renfield a raison de dire qu'il faut toujours savoir tout bien peser avant de décider.
J'ai par exemple bien vu très récemment comment et dans quel cas de figure précis on pouvait bénéficier des avantages d'un Array généré par un "Splitting" (que je déteste pourtant) : lorsqu'il s'agit, par exemple, d'alimenter un autre contrôle.
0
cs_Jack Messages postés 14006 Date d'inscription samedi 29 décembre 2001 Statut Modérateur Dernière intervention 28 août 2015 79
3 juil. 2007 à 23:44
PS : J'avais oublié le "+1" dans l'incrémentage (incrémentation, incrémentement) du Score
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
4 juil. 2007 à 00:09
t'as pas tord, Brunews... ca évite des sauts, on incrémente quoi qu'il arrive...

Renfield
Admin CodeS-SourceS- MVP Visual Basic
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
5 juil. 2007 à 08:13
Re....

Petite idée matinale (just for fun).

Si le text n'est pas trop long, on peut :

- 1) se servir de l'unicode (une seule fois)
- 2) aller chercher le caractère 0 final de chaque élément (caractère, donc) et le remplacer par un caractère "de séparation" (par exemple : @) (une seule fois, donc)
- 3) éclater (split) par rapport à @ ert travailler sur l'array ainsi obtenu (une seule fois, donc)

Début du mécanisme, pour mieux y voir clair :

Private Sub Command2_Click()
   Dim toto As String
   toto = "Voilà à quoi on peut s'amuser"
   toto = StrConv(toto, vbUnicode)
   toto = Replace(toto, Chr$(0), "@")
   MsgBox Trim$(toto)
End Sub
0
3xplo Messages postés 10 Date d'inscription mercredi 13 décembre 2006 Statut Membre Dernière intervention 8 juillet 2007
7 juil. 2007 à 17:55
Bonjour,

excusez-moi, je n'ai pas pu me connecter plus tôt pour problemes personnels.

Merci à tous pour votre aide.


J'ai une autre petite question pour l'affichage, j'aimerais le
dynamiser. Comment faire pour que lorsque l'on clique sur un bouton, la
zone de liste s'initialise avec 26 lignes (1 par lettre), le nombre
associé à chacune étant 0, et qu'au fur et à mesure du traitement du
fichier, la zone de liste se mette à jour ???
0
jmfmarques Messages postés 7666 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 27
7 juil. 2007 à 19:02
Zone de liste ?
De quoi parles-tu ?
D'une Listbox ?
Il n'existe pas de "zone de liste" sous VB6 (la présente section de ce forum)...
0
Rejoignez-nous