Manipulation des fichiers
Jessekamba
Messages postés
54
Date d'inscription
Statut
Membre
Dernière intervention
-
[Dal] Messages postés 6205 Date d'inscription Statut Contributeur Dernière intervention -
[Dal] Messages postés 6205 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour ici, je suis débutant en C et j'ai besoin d'aide.
J'ai un fichier .txt qui contient les mots français, je veux faire un dictionnaire avec un système de prédiction, par exemple lorsque l'utilisateur écrit 'pro' on lui liste tous les mots commençant par pro comme :programme, progrès, prophète,proprement,propriétaire, projet... Plus l'utilisateur écrit plus on élimine les mots n'ayant pas trait à la recherche. Comme dans l"exemple précédent si l'utilisateur écrit 'prop' on ne restera qu'avec prophète, propriétaire et proprement. Dans le cas où il tape un mot qui n'existe pas on lui propose des mots qui sont proches de celui qu'il a écrit.
J'ai un fichier .txt qui contient les mots français, je veux faire un dictionnaire avec un système de prédiction, par exemple lorsque l'utilisateur écrit 'pro' on lui liste tous les mots commençant par pro comme :programme, progrès, prophète,proprement,propriétaire, projet... Plus l'utilisateur écrit plus on élimine les mots n'ayant pas trait à la recherche. Comme dans l"exemple précédent si l'utilisateur écrit 'prop' on ne restera qu'avec prophète, propriétaire et proprement. Dans le cas où il tape un mot qui n'existe pas on lui propose des mots qui sont proches de celui qu'il a écrit.
A voir également:
- Manipulation des fichiers
- Renommer des fichiers en masse - Guide
- Fichiers epub - Guide
- Wetransfer gratuit fichiers lourd - Guide
- Explorateur de fichiers - Guide
- Fichiers bin - Guide
6 réponses
Bonjour,
Concernant ta demande ce que je peux te conseiller c'est d'utiliser "conio.h" notamment la fonction _kbhit(), qui te permettra de récupérer les touches en temps réel. De plus tu va devoir ouvrir ton fichier et y séparer tout les mots. L'algorithme devra fonctionner de la manière suivante:
- L'utilisateur tape une lettre
- Le programme sélectionne tous les mots qui commencent par cette lettre.
- Il affichent ces mots
- Lorsque qu'une nouvelle lettre est appuyée, efface l'écran , affiche les lettres déjà tapée et recommence la recherche
Si tu as besoin de plus de détails sur comment developer chaque étape du programme, ou si tu as de nouvelles questions n'hésites pas à les poser,
Cordialement Christo974
Concernant ta demande ce que je peux te conseiller c'est d'utiliser "conio.h" notamment la fonction _kbhit(), qui te permettra de récupérer les touches en temps réel. De plus tu va devoir ouvrir ton fichier et y séparer tout les mots. L'algorithme devra fonctionner de la manière suivante:
- L'utilisateur tape une lettre
- Le programme sélectionne tous les mots qui commencent par cette lettre.
- Il affichent ces mots
- Lorsque qu'une nouvelle lettre est appuyée, efface l'écran , affiche les lettres déjà tapée et recommence la recherche
Si tu as besoin de plus de détails sur comment developer chaque étape du programme, ou si tu as de nouvelles questions n'hésites pas à les poser,
Cordialement Christo974
Salut Jessekamba,
C'est bizarre de vouloir faire ce type de choses sur la console ... c'est plutôt typiquement une intéraction qu'on trouve dans des programmes avec une interface graphique, ou un navigateur qui dialogue en asynchrone en JavaScript avec un serveur (lequel peut faire tourner un cgi écrit en C pour les performances).
Si tu dois vraiment le faire avec une intéraction en console, tu pourrais voir si tu ne peux pas utiliser une bibliothèque déjà faite pour cela, car simuler une intéraction au clavier à coups de
Sous Linux et systèmes de type Unix, tu as Readline qui est fait pour cela, et qui gère aussi la complétion. Il y a un portage pour Windows de la bibliothèque :
https://tiswww.case.edu/php/chet/readline/rltop.html
http://gnuwin32.sourceforge.net/packages/readline.htm
http://www.gnu.org/
Comme c'est sous GNU GPL, ton programme le sera aussi.
Sinon, pour une bibliothèque C avec une licence plus douce, tu as : https://github.com/antirez/linenoise (mais c'est destiné à des systèmes POSIX, pas Windows). Celle-ci https://github.com/arangodb/linenoise-ng, en C++, gère Windows aussi.
En C, il y a aussi http://thrysoee.dk/editline/ (http://mingweditline.sourceforge.net/?Description pour Windows)
Sur un autre sujet, si tu as beaucoup de mots dans ton fichier, et que les temps de réponse sont critiques, tu pourrais réfléchir à une structure de données sous forme d'arbre pour un algorithme efficace de recherche des possibilités de complétion.
Pour les suggestions de mots mal orthographiés, tu peux voir l'excellent article de Peter Norvig http://www.norvig.com/spell-correct.html et la proposition d'implémentation en C de Marcelo Toledo : http://marcelotoledo.com/how-to-write-a-spelling-corrector/
Dal
C'est bizarre de vouloir faire ce type de choses sur la console ... c'est plutôt typiquement une intéraction qu'on trouve dans des programmes avec une interface graphique, ou un navigateur qui dialogue en asynchrone en JavaScript avec un serveur (lequel peut faire tourner un cgi écrit en C pour les performances).
Si tu dois vraiment le faire avec une intéraction en console, tu pourrais voir si tu ne peux pas utiliser une bibliothèque déjà faite pour cela, car simuler une intéraction au clavier à coups de
_kbhit()(ou plutôt de
_getch()) est loin d'être simple.
Sous Linux et systèmes de type Unix, tu as Readline qui est fait pour cela, et qui gère aussi la complétion. Il y a un portage pour Windows de la bibliothèque :
https://tiswww.case.edu/php/chet/readline/rltop.html
http://gnuwin32.sourceforge.net/packages/readline.htm
http://www.gnu.org/
Comme c'est sous GNU GPL, ton programme le sera aussi.
Sinon, pour une bibliothèque C avec une licence plus douce, tu as : https://github.com/antirez/linenoise (mais c'est destiné à des systèmes POSIX, pas Windows). Celle-ci https://github.com/arangodb/linenoise-ng, en C++, gère Windows aussi.
En C, il y a aussi http://thrysoee.dk/editline/ (http://mingweditline.sourceforge.net/?Description pour Windows)
Sur un autre sujet, si tu as beaucoup de mots dans ton fichier, et que les temps de réponse sont critiques, tu pourrais réfléchir à une structure de données sous forme d'arbre pour un algorithme efficace de recherche des possibilités de complétion.
Pour les suggestions de mots mal orthographiés, tu peux voir l'excellent article de Peter Norvig http://www.norvig.com/spell-correct.html et la proposition d'implémentation en C de Marcelo Toledo : http://marcelotoledo.com/how-to-write-a-spelling-corrector/
Dal
tu as un exemple, ici, qui explique comment utiliser GNU Readline pour gérer la complétion avec la touche tabulation : https://thoughtbot.com/blog/tab-completion-in-gnu-readline
et là : https://github.com/venkatesh20/Autocompleter-in-c un exemple d'implémentation en C d'une organisation des données sous la forme d'un arbre ternaire de recherche permettant une recherche rapide sur la base d'un préfixe sur une base conséquente
Dal. J'ai lu, merci ça va beaucoup m'aider. Mais j'ai une autre question . Comment je peux écrire la fonction qui vérifie si le mot entré se trouve dans le fichier ?Le Langage C n'a pas une fonction comme like en VBA qui compare les données si elles sont les même ? Ou bien il faut un algorithme tout fait ? ?
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { int n, len; char radical[BUFSIZ]; char * dict[] = {'programme','progres','prophete','projet','proprement','proprietaire'}; const int dict_size=6; strncpy(radical,'prop',BUFSIZ); printf("suggestion pour \'%s\':",radical ); len=strlen(radical); for (n=0;n<dict_size;n++){ if (memcmp(radical,dict[n],len )==0) printf("%s",dict[n] ); } printf("\n"); return 0; }
Je viens de corriger dal et là ça passe. J'ai le résultat attendu.
Il persiste encore un autre problème, comment je peux faire pour le faire à partir de mon fichier txt qui contient les mots ?
Dans le code que tu m'as donné le préfixe
Il persiste encore un autre problème, comment je peux faire pour le faire à partir de mon fichier txt qui contient les mots ?
Dans le code que tu m'as donné le préfixe
"prop"est prédéfini dans le code. Mais j'aimerais le demander a l utilisateur, quand il tape on vérifie s'il existe dans le fichier et on lui donne les résultats . C'est là même mon grand problème
Dal regarde un peu ce petit bout de code que j'ai dû taper, lorsque je tape un mot et que je valide on me renvoi tout le contenu du fichier dictionnaire_français.txt
Mais je veux que ce soit le seul mot que je tappe au clavier au lieu de tout le contenu comme je te l'ai demandé tout à l'heure .
Mon algorithme n'est pas bien conçu ???
Mais je veux que ce soit le seul mot que je tappe au clavier au lieu de tout le contenu comme je te l'ai demandé tout à l'heure .
Mon algorithme n'est pas bien conçu ???
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char tab[BUFSIZ];
char buffer[BUFSIZ];
FILE *fp= fopen("dictionnaire_francais.txt","r");
if (fp == NULL){
fputs("Erreur a l ouverture du fichier \n",stderr);
return EXIT_FAILURE;
}
puts("Votre mot");
fgets(tab, sizeof tab,stdin);
puts(tab);
printf("on puts tqb\n");
{
char *p=strchr(tab,'\n');
if (p != NULL)
- p=0;}while (fgets(buffer,sizeof(buffer),fp)){ char *p= strchr(buffer,'\n'); if (p != NULL){ *p='\0'; } puts(buffer); if (strcmp(buffer,tab)==0){ puts("existe"); }}fclose(fp);fp= NULL;return 0;}
Mon code avait pour objectif de répondre à ta question "Le Langage C n'a pas une fonction comme like en VBA qui compare les données si elles sont les même ?" en te donnant un exemple simple d'utilisation de la fonction standard memcmp, pas de faire le programme à ta place. Je ne sais pas si, dans ton cas, un simple tableau de pointeurs sur des chaînes C est pertinent.
comment je peux faire pour le faire à partir de mon fichier txt qui contient les mots ?
Renseigne toi sur les fonctions standard fopen, fgets (pour lire ligne par ligne dans un fichier texte) et fread (pour lire en blocs). Tu devras gérer la mémoire nécessaire avec malloc / free.
Mais j'aimerais le demander a l utilisateur, quand il tape on vérifie s'il existe dans le fichier et on lui donne les résultats
Pour lire quelque chose au clavier, tu peux utiliser des fonctions standard du C comme scanf ou fgets, mais elles interrompront l'exécution du programme tant que l'utilisateur n'aura pas tapé entrée. Si tu veux vraiment un affichage de suggestions qui puissent s'afficher alors que l'utilisateur n'a pas encore validé sa saisie, cela n'existe pas en C standard.
Si GNU readline (qui peut être utilisé pour afficher des suggestions sur la base d'un radical en pressant Tab) ne convient pas à tes besoins, tu peux construire ta propre interface utilisateur avec ncurses, pdcurses, l'API Windows si tu es sous Windows, ou faire quelque chose de très basique avec conio.h.
Tout cela est plus ou moins complexe à mettre en oeuvre, plus ou moins ergonomique, et on ne peut pas faire ces choix à ta place.
A vrai dire, comme indiqué dans mon post d'origine, je ne comprend pas très bien ton projet, ni pourquoi tu fais cela en ligne de commande (et en C). De plus, tu dis que tu es débutant, et ce projet est loin de convenir à un débutant si tu veux vraiment le faire comme tu le dis. Peux-tu en dire plus ?
Dal
comment je peux faire pour le faire à partir de mon fichier txt qui contient les mots ?
Renseigne toi sur les fonctions standard fopen, fgets (pour lire ligne par ligne dans un fichier texte) et fread (pour lire en blocs). Tu devras gérer la mémoire nécessaire avec malloc / free.
Mais j'aimerais le demander a l utilisateur, quand il tape on vérifie s'il existe dans le fichier et on lui donne les résultats
Pour lire quelque chose au clavier, tu peux utiliser des fonctions standard du C comme scanf ou fgets, mais elles interrompront l'exécution du programme tant que l'utilisateur n'aura pas tapé entrée. Si tu veux vraiment un affichage de suggestions qui puissent s'afficher alors que l'utilisateur n'a pas encore validé sa saisie, cela n'existe pas en C standard.
Si GNU readline (qui peut être utilisé pour afficher des suggestions sur la base d'un radical en pressant Tab) ne convient pas à tes besoins, tu peux construire ta propre interface utilisateur avec ncurses, pdcurses, l'API Windows si tu es sous Windows, ou faire quelque chose de très basique avec conio.h.
Tout cela est plus ou moins complexe à mettre en oeuvre, plus ou moins ergonomique, et on ne peut pas faire ces choix à ta place.
A vrai dire, comme indiqué dans mon post d'origine, je ne comprend pas très bien ton projet, ni pourquoi tu fais cela en ligne de commande (et en C). De plus, tu dis que tu es débutant, et ce projet est loin de convenir à un débutant si tu veux vraiment le faire comme tu le dis. Peux-tu en dire plus ?
Dal
sinon, par rapport à ton code là : https://forums.commentcamarche.net/forum/affich-35400720-manipulation-des-fichiers#17
il affiche toute la liste de mots sur chaque ligne du fichier parce que tu fais un
si tu veux afficher ce mot seulement s'il existe dans le dictionnaire, met ce
l'indentation de ton code n'est pas lisible
il affiche toute la liste de mots sur chaque ligne du fichier parce que tu fais un
puts(buffer);après avoir lu chaque ligne avec fgets.
si tu veux afficher ce mot seulement s'il existe dans le dictionnaire, met ce
puts(buffer);dans les accolades du
if (strcmp(buffer,tab)==0)...
l'indentation de ton code n'est pas lisible
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char tab[BUFSIZ]; char buffer[BUFSIZ]; FILE * fp=fopen("dictionnaire_francais.txt","r"); if (fp == NULL){ fputs("Erreur a l ouverture du fichier \n",stderr); return EXIT_FAILURE; } puts("Votre mot"); fgets(tab, sizeof tab,stdin); puts(tab); { char *p=strchr(tab,'\n'); if (p != NULL) p='\0' ; } while (fgets(buffer,sizeof(buffer),fp)){ char *p= strchr(buffer,'\n'); if (p != NULL){ *p='\0'; } if (strcmp(buffer,tab)==0){ puts("existe"); puts(buffer); } } fclose(fp); fp= NULL; return 0; }
tu n'as toujours pas corrigé la ligne 20 comme je te disais de le faire https://forums.commentcamarche.net/forum/affich-35400720-manipulation-des-fichiers#20
remplace
remplace
p='\0' ;par
*p='\0';sinon tu écrases ton pointeur
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Je viens de remplacer maintenant mais, ça ne change rien. On me renvoi toujours le même mot
ton code corrigé comme je te l'indique :
avec dictionnaire_francais.txt comprenant (avec les accents retirés, comme tu l'as écris dans ton code là https://forums.commentcamarche.net/forum/affich-35400720-manipulation-des-fichiers#12) :
compilé et exécuté avec différentes valeurs :
renvoie bien "existe" si le mot existe dans le fichier.
Dal
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char tab[BUFSIZ]; char buffer[BUFSIZ]; FILE * fp=fopen("dictionnaire_francais.txt","r"); if (fp == NULL){ fputs("Erreur a l ouverture du fichier \n",stderr); return EXIT_FAILURE; } puts("Votre mot"); fgets(tab, sizeof tab,stdin); puts(tab); { char *p=strchr(tab,'\n'); if (p != NULL) *p='\0'; } while (fgets(buffer,sizeof(buffer),fp)){ char *p= strchr(buffer,'\n'); if (p != NULL){ *p='\0'; } if (strcmp(buffer,tab)==0){ puts("existe"); puts(buffer); } } fclose(fp); fp= NULL; return 0; }
avec dictionnaire_francais.txt comprenant (avec les accents retirés, comme tu l'as écris dans ton code là https://forums.commentcamarche.net/forum/affich-35400720-manipulation-des-fichiers#12) :
programme
progres
prophete
projet
proprement
proprietaire
compilé et exécuté avec différentes valeurs :
$ gcc -Wall 35400720.c
$ ./a.out
Votre mot
pprojet
pprojet
$ ./a.out
Votre mot
projet
projet
existe
projet
$
renvoie bien "existe" si le mot existe dans le fichier.
Dal
Sinon, comme indiqué précédemment, tu devrais plutôt stocker en mémoire les mots du dictionnaire, car tu ne vas pas ouvrir le fichier et parcourir son contenu à chaque fois que tu voudras vérifier un mot.
Tu peux éventuellement utiliser la méthode décrite dans ce post :
https://forums.commentcamarche.net/forum/affich-35265601-novice-dans-la-programmation#17
pour charger la totalité du fichier avec fread et parser le contenu en sous-chaînes représentant les mots avec strtok et
Dal
Tu peux éventuellement utiliser la méthode décrite dans ce post :
https://forums.commentcamarche.net/forum/affich-35265601-novice-dans-la-programmation#17
pour charger la totalité du fichier avec fread et parser le contenu en sous-chaînes représentant les mots avec strtok et
'\n'comme caractère séparateur.
Dal
Note que dans cet exemple, les chaînes sont stockées dans un tableau.
Si ton dictionnaire est volumineux, et que tu as fait le choix d'une structure de données sous forme de tableau, il se peut que l'exécution de ton programme soit étranglée si tu fais des recherches séquentielles dans le tableau, qui peuvent pénaliser les temps d'exécution. Il te faudra alors réfléchir à une structure de données et algorithme de recherche plus efficace.
J'ai déjà mentionné les arbres ternaire de recherche, qui paraissent adaptés à une recherche par radical.
Sin, en fait, les recherches par radical ne t'intéressent pas, pour des recherches à l'identique, les hash sont rapides, mais ils sont complexes à mettre en oeuvre.
Autrement, pour des recherches à l'identique (et dans une certaine mesure par radical), tu peux obtenir des performances acceptables de recherche sur un tableau ordonné avec un algorithme de recherche dichotomique. C'est sans doutes l'optimisation la plus à la portée d'un débutant, si tu as besoin d'optimiser les temps d'exécution :
https://fr.wikipedia.org/wiki/Recherche_dichotomique
En tout cas, bon courage pour la finalisation de ton projet :-)
Dal
Si ton dictionnaire est volumineux, et que tu as fait le choix d'une structure de données sous forme de tableau, il se peut que l'exécution de ton programme soit étranglée si tu fais des recherches séquentielles dans le tableau, qui peuvent pénaliser les temps d'exécution. Il te faudra alors réfléchir à une structure de données et algorithme de recherche plus efficace.
J'ai déjà mentionné les arbres ternaire de recherche, qui paraissent adaptés à une recherche par radical.
Sin, en fait, les recherches par radical ne t'intéressent pas, pour des recherches à l'identique, les hash sont rapides, mais ils sont complexes à mettre en oeuvre.
Autrement, pour des recherches à l'identique (et dans une certaine mesure par radical), tu peux obtenir des performances acceptables de recherche sur un tableau ordonné avec un algorithme de recherche dichotomique. C'est sans doutes l'optimisation la plus à la portée d'un débutant, si tu as besoin d'optimiser les temps d'exécution :
https://fr.wikipedia.org/wiki/Recherche_dichotomique
En tout cas, bon courage pour la finalisation de ton projet :-)
Dal
Justement j'ai besoin de plus de détails pour développer chaque étape, si peux m'aider sur ce coup là