1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
| /*
* File: txtanalyzer.c
* Author: Dimitri "Hurukan" <soundlord@gmail.com>
*
* Créé le March 1, 2022, 4:59 AM
*/
// ****************************************************************************
// HISTORIQUE
// ****************************************************************************
// ****************************************************************************
// Fichiers de définitions
// ****************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include "analyzer.h"
// ****************************************************************************
// Déclaration des constantes symboliques
// ****************************************************************************
// ****************************************************************************
// Déclaration des variables globales, externes, ...
// ****************************************************************************
// ****************************************************************************
// SECTION : prototypes des fonctions en test pour CE code source
// ****************************************************************************
char* extractWord(char*);
int IsExists(char*,t_Word*,int);
void Insert(char*,t_Word*,int);
/*
* FONCTION PRINCIPALE
*/
int main(int argc,char** argv)
{
#ifdef OLD
char str[10000],c='a';
int imot=0,jlettre=0, count=0;
FILE *fp;
fp=fopen("hauts.txt","r");
/* printf("Entrer une chaine de caractere: ");
gets(str);*/
while (!feof(fp))
{
c=fgetc(fp);
if(c== ' ' || c== '\t' || c== '\n') count++;
else printf("%c",c);
}
printf("\n il y a %d mots\n",count);
char tabmots[count][30];
printf("%d\n",sizeof(tabmots));
fp=freopen("hauts.txt","r",fp);
while (!feof(fp))
{
c=fgetc(fp);
if((c<65) || (c>90) || (c<97) || (c>122)) {
//printf("%s\n",tabmots[imot]);
imot++;
jlettre=0;
}
else
{
tabmots[imot][jlettre++]=c;
printf("%d \t %c ",c,c);
}
}
/* for(i = 0; str[i] != '\0'; i++) //compter nombre total mot dans le texte
{
if(str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
{
count++;
}
}
printf("il y a %d mots\n",count);*/
fclose(fp);
#endif
char *texte; // ici je vais mettre tout en mémoire pour ne pas devoir faire des accès disques (si les fichiers font moins de 4.2Go ça devrait aller ^^)
FILE *descFichier;
descFichier=fopen("texte.txt","r");
if(!descFichier) return(EXIT_FAILURE);
long tailledufichier;
fseek(descFichier,0L,SEEK_END); // je me positionne dans le fichier à la fin de celui-ci...
tailledufichier=ftell(descFichier); // je récupère la taille du fichier
fseek(descFichier,0L,SEEK_SET); // je reviens au début du fichier sinon dès que je vais lire je vais me taper un EOF ^^
texte=(char*)calloc(tailledufichier+1,sizeof(char));
if(!texte) return(EXIT_FAILURE);
fread(texte,1,tailledufichier,descFichier);
// je devrais faire des tests mais j'ai la flemme :{
// Nous avons le texte en mémoire... on peut fermer le descripteur
fclose(descFichier);
// Nous allons analyser le texte en considérant que les mots sont séparés par
// soit un espace (32 ASCII) soit par un caractère de ponctuation (selon les normes dactylographiques)
// Pour la répétition des mots là par réflexe j'utiliserais une de mes librairies mais pour "simplifier" nous passerons par "autre chose"
// Ma librairie permet la gestion de listes/files... ce serait bien d'avoir cela pour notre projet...
// Pour chaque mot il faut lui associer un nombre indiquant le nombre de fois qu'il apparaît dans le texte...
// Sans ma librairie je serais tenté de créer un tableau de structures le soucis c'est que ce tableau devra avoir une taille fixe
// et c'est là que ma librairie va me manquer ^^
// On va donc compter le nombre de mots c'est ce qu'il y a de plus facile...
// Pour les occurences on va devoir se creuser un peu si je ne peux pas utiliser ma librairie...
// Dans le fichier analyzer.h j'ai défini une structure:
//typedef struct s_Word
//{
// char *pPattern;
// int occurence;
//}t_Word;
// Qui va nous servir par la suite...
long curseurlecture=0L;
long nbMots=0L;
t_Word tabMots[tailledufichier/3]; // normalement un mot est composé d'au moins trois caractères sinon ce sont des prépositions ici c'est juste pour contourner le fait que je ne sache utiliser ma librairie
// JE HAIS de faire ceci mais j'ai pas le choix ici (ouin ouin ma librairie mes listes et mes piles etc...)
memset(tabMots,0,(tailledufichier/3)*sizeof(t_Word)); // on met tout à zéro en mémoire à partir de l'adresse de tabMots (sinon on risque des surprises !!)
while(curseurlecture<tailledufichier)
{
//lecture caractère par caractère et détection de l'espace et du retour de ligne plus ponctuation...
// ce serait "plus simple" avec les expression rationelles/régulières mais je ne sais pas si tu as déjà vu ces mécanismes (le Perl est plus adapté pour ce genre de traitements ^^)
if(texte[curseurlecture]<10 && texte[curseurlecture]>=0)
{
curseurlecture++;
continue;
}
if(texte[curseurlecture]==12 || texte[curseurlecture]==11)
{
curseurlecture++;
continue;
}
if(texte[curseurlecture]>=14 && texte[curseurlecture]<=31)
{
curseurlecture++;
continue;
}
if(texte[curseurlecture]==10 || texte[curseurlecture]==13)
{
curseurlecture++;
continue;
}
// ici je traite le cas de la parenthèse dans les règles dactylographiques communes
if(texte[curseurlecture]==' ' && texte[curseurlecture+1]==')')
{
curseurlecture++; // ')' ne doit pas être traité
continue;
}
// ici je traite le point final du texte
if(texte[curseurlecture]=='.' && curseurlecture>=tailledufichier-1)
{
break;
}
if(texte[curseurlecture]==' ' || texte[curseurlecture]=='.' || texte[curseurlecture]==',' || texte[curseurlecture]==';' || texte[curseurlecture]==':' || texte[curseurlecture]=='.')
{
if(texte[curseurlecture+1]==' ') // cas des doubles espaces
{
curseurlecture++;
continue;
}
if(texte[curseurlecture+1]=='-')
{
curseurlecture++;
continue;
}
if(texte[curseurlecture+1]=='.') // cas des "trois petits points"
{
curseurlecture++;
continue;
}
// le mot se trouve donc APRES le caractère de ponctuation <--
char *targetWord=extractWord(&texte[curseurlecture+1]);
int indice=IsExists(targetWord,tabMots,tailledufichier/3);
if(indice>=0)
{
tabMots[indice].occurence++;
}
else Insert(targetWord,tabMots,tailledufichier/3);
nbMots++;
}
// dans les textes anglophones je ne pense pas qu'il existe des césures du style anglo-saxon... en français il faut considérer qu'il s'agit d'un mot et non deux...
// il y a un petit risque de "effet de bord" dans l'instruction qui suit...
if(texte[curseurlecture]=='-' && (texte[curseurlecture+1]<='Z' && texte[curseurlecture+1]>='A') && (texte[curseurlecture+1]<='z' && texte[curseurlecture+1]>='a'))
{
/*char *targetWord=extractWord(&texte[curseurlecture+1]);
int indice=IsExists(targetWord,tabMots,tailledufichier/3);
if(indice>=0)
{
tabMots[indice].occurence++;
}
else Insert(targetWord,tabMots,tailledufichier/3);*/
nbMots++;
}
// pour les autres caractères de ponctuation je ne pense pas qu'ils puissent indiquer l'existence d'un mot qui les suit... sauf peut-être la parenthèse
if(texte[curseurlecture]=='(' && texte[curseurlecture+1]==' ')
{
curseurlecture+=2; // ' ' ne doit pas être traité une seconde fois
nbMots++;
}
curseurlecture++;
}
printf("Nombre de mots dans le texte: %05ld\n",nbMots);
printf("Résumé: \n");
// Je HAIS faire ceci... blah blah blah
int position=0;
while(position<tailledufichier/3)
{
if(tabMots[position].pPattern!=NULL) printf("[%s] %02d\n",tabMots[position].pPattern,tabMots[position].occurence);
position++;
}
return(EXIT_SUCCESS);
}
// ****************************************************************************
// SECTION : implémentation des fonctions
// ****************************************************************************
char* extractWord(char *startpos)
{
long adressedepart=(long)startpos;
long taillemot=0L;
if(startpos==NULL) return NULL;
while((*startpos<='Z' && *startpos>='A') || (*startpos<='z' && *startpos>='a'))
{
startpos++;
}
// ...si nous arrivons ici c'est qu'il s'agit d'un mot (pour la césure nous verrons plus tard
taillemot=(long)startpos-adressedepart;
if(taillemot<=0) return NULL;
char *tmp=(char*)calloc(taillemot+1,sizeof(char));
strncpy(tmp,(char*)adressedepart,taillemot);
return tmp;
}
int IsExists(char *pattern, t_Word *source,int size)
{
if(pattern==NULL) return -1;
// je déteste faire ça mais j'ai pas le choix ici
int position;
for(position=0;position<size;position++)
{
if(source[position].pPattern==NULL) continue;
if(strcmp(source[position].pPattern,pattern)==0)
{
return position;
}
}
return -1;
}
void Insert(char *word,t_Word *target,int size)
{
// nouvelle entrée
// c'est horrible je sais mais sans ma librairie j'écris de la m...
if(word==NULL) return;
int position=0;
for(;position<size;position++)
{
if(target[position].pPattern==NULL)
{
target[position].pPattern=(char*)calloc(strlen(word)+1,sizeof(char));
strcpy(target[position].pPattern,word);
target[position].occurence=1;
break;
}
}
} |
Partager