Projet bloquer

Fermé
baptous - Modifié par baladur13 le 9/01/2016 à 18:07
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 - 11 janv. 2016 à 18:04
Bonjour j'ai comme projet ( a faire dans mes études ) de crée un programme qui analyse un texte qui a pour but de:

-calculer le nombre de mots

-déterminer la longueur moyenne des mots

-donner l'occurence d'un mot choisit

- afficher la liste des mots répétés ( il me reste que cette partie a faire mais je n'y arrive point )

avec ce programme j'ai du y joindre un texte plutot une poésie.

voici mon programme

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *lire_mot ();

main()
{

    char texte [500];
    char mot [256],c;
    int n,i,l,oc,s,nbmots;
    float m ;
    FILE *f;
    char *token;

    //f=fopen("H:\\BUREAUTIQUE\\poesieminiprojet.txt","r");
    //f=fopen ("\\Ordinateur\\miniprojet\\poesieminiprojet.txt","r");
     f=fopen ("C:\\miniprojet\\poesieminiprojet.txt","r");
    if (f==NULL)
    {
        printf("Probleme fichier non trouvé");
        return(1);
    }
    n=fread(texte,sizeof(char),400,f);
    if (n<400)
    {
        printf("Probleme");
        return(1);
    }
    texte[400]='\0';
    fclose(f);
    //printf("%s",texte);


    printf( "=====================\n");

    /* get the first token */
    token = strtok(texte, " " );

    /* walk through other tokens */
    oc=0;
    s=0;
    n=0;
    while( token != NULL )
    {
        l=strlen(token);
        printf( "%s (%d)\n", token ,l);
        token = strtok(NULL, " ");
        if (token==NULL) {
            continue;
        }
        //printf( "===================== \n");
        /*
                //gets(texte);
                n=1;
                strcpy (mot,lire_mot(token,n));
                s=0;
                oc = 0;


*/
        char *motchoisit = "les";
        if (strcmp(token,motchoisit)==0)
        {
            oc++;
        }
        s=s+l;
        n++;
    }

   printf( ">>>>>>>>>>>>>>>\n");
    nbmots = n-1;
    m = 1.*s/nbmots;
    printf ("\n n %d", nbmots);
    printf ("\n s %d ", s);
    printf ("\n m %f", m);
    //printf ("\n s/n %d %d", s,nbmots);
    printf ("\n oc %d",oc);

    return 0;

}


En espérant que vous puissiez m'aider, merci d'avance

EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.

1 réponse

paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 25
10 janv. 2016 à 14:54
Je n'ai pas testé le programme, et je ne comprends pas tout à fait ce que tu veux comme aide.
Néanmoins, il y a plusieurs petits trucs que j'ai pu voir en parcourant le programme des yeux (peut-être que certains sont donc faux) :

Lignes 10-15 : tu n'initialises aucune variable ici, par conséquent tu dois le faire par la suite... C'est assez déconseillé. Tu pourrais faire quelque chose comme :
    char texte[500] = "", mot[256] = "";
    char c = 0;
    int n = 0, i = 0, l = 0, oc = 0, s = 0, nbmots = 0;
    float m = 0;
    FILE *f = NULL;
    char *token = NULL;

Si tu fais ceci, tu te mets à l'abris de pas mal de bugs et tu peux supprimer les lignes 42-43 (mais pas la ligne 44 vu que tu as déjà utilisé n avant et que tu dois donc le réinitialiser. Essaie d'ailleurs d'uiliser des variables différentes, on n'est pas à 4 octets de mémoire près).

Lignes 49-52: Ces lignes doivent se trouver à la fin de la boucle, puisque tu utilises token par la suite dans la boucle. De plus, des mots ne sont pas séparés que par des espaces et peuvent aussi être séparés par de la ponctuation. Je te proposes donc de donner, comme second argument à la fonction strtok, quelque chose comme " ,;?!:'()" (ce qui est aussi valable ligne 39).

Lignes 25-31: Ton tableau texte fait 500 cases... Pourquoi se limiter à 400 dans le fread ? Puis, fread peut retourner moins de 400 si le texte fait, tout simplement, moins de 400 caractères. Le test d'erreur doit donc se faire avec la valeur 0. Ensuite, si le texte fait moins de 400 caractères, le caractère '\0' doit se retrouver tout de même à la fin du texte. Je te propose donc ce code :
    n = fread(texte, sizeof(char), 499, f);
    if (n == 0)
    {
        printf("Probleme\n");
        return(1);
    }
    texte[n] = '\0';


Ligne 73: Pourquoi n-1 ? Ce serait plutot n+1, non ? Et si tu initialises ta variable n à 1 plutôt qu'à 0, tu n'as même plus besoin de la variable nbmots et tu peux directement utiliser n comme le nombre de mots.

Ligne 63: Tu ne peux pas initialiser motchoisit à "les" parce que motchoisit n'est pas une chaîne de caractères, mais un pointeur ! Il faut donc faire:
        char motchoisit[] = "les";

Ligne 74: Pourquoi 1.*s et pas tout simplement s ??

Peut-être qu'il y a d'autres erreurs (je répète que je n'ai pas testé le programme).

En espérant que cela t'aidera,
paly2
0
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 25
Modifié par paly2 le 10/01/2016 à 15:03
Et pour trouver la liste des mots répétés, il faut que pour chaque mot du texte (donc, dans ta boucle que tu as déjà actuellement), tu parcoures à nouveau tout ton texte pour savoir si le mot est présent une deuxième fois. Mais comme tu ne peux pas réutiliser strtok de façon récursive, n'oublie pas de le remplacer par strtok_r. Si tu ne comprends pas ce que je veux dire, n'hésite à me demander des précisions.
N'oublie pas que ceci multiplierait beaucoup le temps que prendrait l'exécution de ton programme, même si pour un petit texte de 500 caractères tu ne verras sans doute pas la différence (en revanche, pour un gros texte d'un million de caractères...).
0
Bonjour suite au modification que vous m'avais proposer j'ai rectifier le programme.

Par rapport a ce que vous me dites a la toute fin je dois faire quoi avec strtok pour en faire l'affichage de liste des mots répétés?
0
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 25
Modifié par paly2 le 10/01/2016 à 21:27
Pour afficher la liste des mots répétés, il faut, dans la boucle actuelle qui parcourt tous les mots, faire une autre boucle qui parcourt tous les mots pour trouver un mot identique au mot actuel.
Les deux boucles utilisent donc strtok, mais strtok ne peut fonctionner que sur une chaîne à la fois (si on rappelle strtok avec autre chose que NULL en premier paramètre, on perd l'endroit où on était avec la chaîne précédente).
Du coup, il existe une autre fonction, strtok_r, qui permet de gérer plusieurs chaînes en même temps.
Ce code d'exemple devrait fonctionner (à vérifier tout de même) :
char *saveptr1, *saveptr2;
char str1[] = "ceci est la premiere chaine", str2[] = "ceci est la deuxieme chaine";
printf("Premier token de la premiere chaine: %s\n", strtok_r(str1, " ", &saveptr1));
printf("Premier token de la deuxieme chaine: %s\n", strtok_r(str2, " ", &saveptr2));
printf("Deuxieme token de la premiere chaine: %s\n", strtok_r(NULL, " ", &saveptr1));
printf("Deuxieme token de la deuxieme chaine: %s\n", strtok_r(NULL, " ", &saveptr2));


Par contre cette fonction n'est pas un standard du C, et peut-etre qu'elle n'existe pas sous Windows (en tout cas elle existe sous GNU/Linux).
0
La fonction strtok_r ne fonctionne pas donc j'ai fait ceci

char mots[250][100];
int countMots[250];

while( token != NULL )
{
char motCurrent = realloc(token, 100 * sizeof(char));
for (int i = 0; i < 250; i++);
{
if (mots[i] == NULL)
{
mots[i] = motCurrent;
countMots[i] = 1;
break;
}

if(strcmp(mots[i], motCurrent) == 0)
{
countMots[i]++;
break;
}
}
}


Mais il me découvrir 2erreurs une avec le char 100 il me dit erreur d'incompatibilité de type et une au for
0
paly2 Messages postés 254 Date d'inscription vendredi 29 août 2014 Statut Membre Dernière intervention 15 février 2018 25
Modifié par paly2 le 11/01/2016 à 18:07
Pour tes erreurs, tu as juste oublié l'astérisque qui permet de définir un pointeur lors de la définition de la variable motCurrent :
char* motCurrent =

De plus, tu as mis un point-virgule à la fin de la ligne de ton for. Pour le compilateur, cela veut dire qu'il n'y a pas de bloc délimité par des accolades après le for, d'où la raison probable de ton erreur (puisqu'il y a quand même des accolades).

Mais je ne comprends pas trop ce que tu veux faire avec ton code... Essaie peut-être quelque chose comme ça :
Code à mettre avant ta boucle :
char mots[250][100] = {{'\0'}};
/* Sur cette ligne, on suppose qu'il y a 250 mots au maximum, ce qui est probablement faux. Prévoir plutôt un tableau dynamique. */

Code à mettre dans ta boucle:
/* n est la variable contenant le nombre de mots, incrémentée à chaque tour de boucle (déjà présente dans le code précédent) */
strcpy(mots[n], token);
for (int i = 0; i < n; i++)
{
 if(strcmp(mots[i], token) == 0)
  printf("Le mot %s est répété.\n", token);
}

Je n'ai pas testé le code ci-dessus, verifie donc qu'il ne contient pas d'erreurs.

En effet, si tu fais comme ceci, tu peux tout à fait garder strtok dans ta boucle comme tu le faisais.
0