Manipulation des fichiers

Fermé
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020 - 5 juin 2018 à 07:39
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 - 14 juin 2018 à 19:28
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.
A voir également:

6 réponses

christo974 Messages postés 94 Date d'inscription lundi 23 juillet 2012 Statut Membre Dernière intervention 5 juin 2019 5
Modifié le 6 juin 2018 à 04:58
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
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
6 juin 2018 à 09:38
Merci Christo947.
Justement j'ai besoin de plus de détails pour développer chaque étape, si peux m'aider sur ce coup là
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 6 juin 2018 à 14:17
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
_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
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
7 juin 2018 à 15:59
Dal j'ai consulté différents liens que tu m'a donné mais je suis toujours butté. Tu n'as pas d'autres qui explique au mieux pour que je voie par où commencer parce que c'est le début qui m'est difficile
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
7 juin 2018 à 18:09
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
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
7 juin 2018 à 18:22
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
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
9 juin 2018 à 06:40
Merci dal. Je consulte ces liens et je te dirais quoi si j'ai toujours du mal à débuter. Je suis content que tu prenne le temps de me lire.
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
9 juin 2018 à 09:10
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 ? ?
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
11 juin 2018 à 12:36
#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;
}
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 11 juin 2018 à 13:27
En C, le délimiteur de chaînes est le guillemet
"
par exemple
"programme"
et pas l'apostrophe (qui est le délimiteur valable pour un (seul) char par exemple
'p'
).
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
11 juin 2018 à 13:46
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
"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
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
11 juin 2018 à 14:25
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 ???

#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;}
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
11 juin 2018 à 16:06
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
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 11 juin 2018 à 18:20
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
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
0
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
12 juin 2018 à 10:41
#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;
} 
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
12 juin 2018 à 10:56
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
p='\0' ;
par
*p='\0';
sinon tu écrases ton pointeur
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
12 juin 2018 à 10:58
note que 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.
0

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

Posez votre question
Jessekamba Messages postés 54 Date d'inscription mercredi 21 juin 2017 Statut Membre Dernière intervention 10 février 2020
12 juin 2018 à 11:00
Je viens de remplacer maintenant mais, ça ne change rien. On me renvoi toujours le même mot
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 12 juin 2018 à 11:23
ton code corrigé comme je te l'indique :
#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
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 12 juin 2018 à 19:54
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
'\n'
comme caractère séparateur.

Dal
0
[Dal] Messages postés 6194 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 11 octobre 2024 1 092
Modifié le 14 juin 2018 à 19:30
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
0