Problème de logique

Résolu/Fermé
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019 - Modifié le 24 févr. 2019 à 21:14
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 - 4 mars 2019 à 21:34
Bonjour,
j'ai un projet de quizz à faire et je dois coder une fonction pour supprimer tous les thèmes et j'ai ça comme prototype. Je vois pas comment je pourrais faire pour faire ça
int supprimerTousLesThemes()
{
    return -1;
}

elle :
o supprime tous les thèmes stockés.
o renvoie le nombre de thèmes qui ont été supprimés.

Configuration: Windows / Chrome 72.0.3626.109

3 réponses

yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 Ambassadeur 1 557
23 févr. 2019 à 19:12
bonjour, où les thèmes sont-ils stockés?
1
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
23 févr. 2019 à 23:09
D'après ce qu'on me demande, les données ne sont pas persistées et sont donc stockées dans des tables statiques en mémoire
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557 > Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
24 févr. 2019 à 12:28
connais-tu la structure de ces tables statiques, as-tu le code qui y enregistre les données?
0
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
Modifié le 24 févr. 2019 à 21:14
Tout ce qu'on m'a donné c'est ça :
#include "../src/themes.h"

static struct Theme themes[NB_THEMES_MAX];
static int nbThemes=0;

int supprimerTheme(int identifiant)
{
    return -1;
}

int supprimerTousLesThemes()
{
    return -1;
}


Et vu que c'est un projet de groupe, je sais pas comment les autres vont fonctionner donc j'dois me débrouiller avec ça et je vois pas comment je peux faire.
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557 > Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
Modifié le 24 févr. 2019 à 14:35
souvent, un projet de groupe implique une collaboration entre les personnes formant le groupe. cette collaboration est-elle interdite ou impossible? comment le travail a-t'il été réparti? qui a décidé que tu allais faire quelle partie du travail? qui va réaliser themes.h?
pour préparer cette collaboration, tu peux déjà réfléchir à ce que devra faire supprimerTousLesThemes(): quelle seront les différences entre "avant" et "après"?
0
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
Modifié le 24 févr. 2019 à 21:14
On vient de seulement de me donner le theme.h avec que je devais compléter dans celui-ci càd SupprimerTheme et SupprimerTousLesThemes:
#ifndef THEMES_H_INCLUDED
#define THEMES_H_INCLUDED
#include <string.h>
#define NB_THEMES_MAX 100

struct Theme {
    int identifiant;
    char libelle[50];
};

 // renvoie le nombre de themes stockés.
 int nombreThemes();

 // compare les 2 thèmes reçus en paramètre.
 // si ils ont le même identifiant et le même libellé, la fonction renvoie 1.
 // si ce n'est pas le cas, elle renvoie 0.
 int themesIdentiques(struct Theme theme1, struct Theme theme2);

 // compare les 2 thèmes reçus en paramètre. La comparaison se fait sur les libellés.
 // si le libellé du thème 1 se trouve avant le libellé du thème 2 dans l'ordre lexicographique, elle renvoie un nombre <0.
 // si le libellé du thème 2 se trouve avant le libellé du thème 1 dans l'ordre lexicographique, elle renvoie un nombre <0.
 // si les libellés sont identiques, elle renvoie 0.
 // Utilisez la fonction strcmp()
 int comparerThemes(struct Theme theme1, struct Theme theme2);

 // ajoute un theme.
 // cette fonction doit affecter un identifiant au thème reçu en paramètre.
 // elle renvoie l'identifiant affecté au thème.
 // si table est pleine, elle renvoie 0.
 int ajouterTheme(struct Theme theme);


 // garnit le tableau reçu en paramètre avec les thèmes stockés.
 void listerThemes(struct Theme themes[]);

 // recherche le libellé du thème dont on reçoit l'identifiant en paramètre
 // si le thème identifié est présent, on recopie son libellé dans le paramètre libelle. On renvoie 1.
 // si le thème n'est pas présent, on affecte une chaine vide au paramètre libelle. On renvoie 0.
 int rechercherLibelleTheme(int identifiant, char libelle[]);

 // modifie le libellé du thème identifié par l'identifiant reçu en paramètre.
 // si le thème est présent, son libellé est modifié. La valeur 1 est renvoyée.
 // si aucun thème ne correspond à cet identifiant, la fonction renvoie 0.
 int modifierTheme(int identifiant, char nouveauLibelle[]);

 // supprime un thème.
 // si l'identifiant reçu en paramètre correspond à un thème stocké, celui-ci est supprimé et elle renvoie 1.
 // si l'identifiant reçu en paramètre ne correspond à aucun thème stocké, elle renvoie 0.
 int supprimerTheme(int identifiant);

 // supprime tous les thèmes stockés.
 // renvoie le nombre de thèmes qui ont été supprimés.
 int supprimerTousLesThemes();

// garnit le tableau reçu en paramètre avec les thèmes triés de façon ascendante sur leur libellé.
 void listerThemesTries(struct Theme themes[]);


#endif // THEMES_H_INCLUDED


C'est tout ce que j'ai eu pour le moment du chef de groupe
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié le 25 févr. 2019 à 14:16
Salut Natsuko410,

Je pense que c'est une fausse piste que d'envisager te servir de
int supprimerTheme(int identifiant);
pour
int supprimerTousLesThemes();
, compte tenu de ta situation, car tu ne sais pas comment lister les identifiants existants, vu que tu n'as pas d'interface définie te permettant d'obtenir cette information, et que tu ne fais pas toi même l'implémentation de la partie du code qui affecte les identifiants à des thèmes ajoutés....

C'est la fonction appelante qui va indiquer à
int supprimerTheme(int identifiant);
l'identifiant à utiliser.

Tu dois faire autrement.

S'agissant du format des identifiants, tu sais qu'il s'agit d'un entier signé et qu'il peut valoir n'importe quelle valeur pouvant être représentée par un
int
au choix de la personne qui implémente cette partie,... toute sauf une.

Et, par élimination, cette valeur est celle qui devrait nécessairement représenter une case "vide" du tableau.

Tu détermines cela en lisant attentivement le commentaire descriptif des entrées et sorties de
int ajouterTheme(struct Theme theme);
et leur signification.

Armé de cette seule information, tu dois être capable de supprimer tous les thèmes, même sans savoir à l'avance quel est l'identifiant qui a pu être octroyé aux différents thèmes stockés.

Dal
1
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
Modifié le 25 févr. 2019 à 14:46
C'est vrai qu'après réflexion, ça me posaient plus de problèmes que ça n'en résolvaient, mais ça restait bien pensé. Mais du coup je reviens un peu à la case départ...
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557 > Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
25 févr. 2019 à 15:42
ne suffit-il pas d’appeler listerThemes pour avoir la liste des identifiants des thèmes, et d'ensuite appeler supprimerTheme pour supprimer chacun des identifiants?
0
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
Modifié le 25 févr. 2019 à 16:09
woaw t'as une bonne vision d'ensemble, j'aurais jamais pensé à ça mais au final elle ne fait que garnir une table si j'en crois le code

// garnit le tableau reçu en paramètre avec les thèmes stockés.
void listerThemes(struct Theme themes[]);
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié le 25 févr. 2019 à 20:25
utiliser
listerThemes()
, comme le propose yg_be est, en principe, une bonne chose car tu encapsules l'usage des données en renvoyant la responsabilité de déterminer ce qui est un identifiant d'un thème à cette fonction (question @yg_be: et cette fonction, comment fait-elle pour distinguer si un entier stocké dans le tableau de référence représente un identifiant ou représente un emplacement vide ?)

personnellement, malgré son nom suggestif et prometteur pour faire de l'encapsulation, je trouve son descriptif pas très convainquant... pour cela il faudrait que l'on ait l'assurance que la "garnissage" liste les éléments séquentiellement à partir de l'index 0 et jusqu'à l'index nbThemes-1 ... ce comportement, bien que raisonnable, n'est pas explicité, tout ce qu'on sait c'est qu'un tableau est "garnit avec les thèmes stockés", mais c'est peut-être une question que tu peux poser pour compléter la spécification de
listerThemes()
...

on voit aussi que la taille du tableau passé en paramètre n'est pas indiquée, et qu'il est probable que le tableau doive être un tableau de taille NB_THEMES_MAX et tout ce qu'on saura c'est que le tableau contient des emplacements pleins et des emplacements vides :-)
0
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
Modifié le 26 févr. 2019 à 20:35
Après avoir réfléchis un peu, j'en suis là
#include "../src/themes.h"

static struct Theme themes[NB_THEMES_MAX];
static int nbThemes=0;

int supprimerTheme(int identifiant)
{
    // Declaration
    int i=0;
    int flag=0;
    // Traitement
    while(i<nbThemes && flag==0)
    {
        if(themes[i].identifiant!=identifiant) i++;
        else flag=1;
    }
    if (flag==1){
        //supprime le theme correspondant à l'identifiant
        return 1; // La fonction a supprimer le theme
    }
    else
    {
        return 0; // La fonction n'a pas trouve le theme
    }
    return -1;
}

Pour vous je suis bien parti ou je suis à côté de la plaque ? Et je vois pas comment faire pour supprimer l'identifiant et le libellé du thème concerné.

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

Merci d'y penser dans tes prochains messages.


Merci d'y penser dans tes prochains messages.
0
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
2 mars 2019 à 12:40
Du coup, je recommences depuis le début, et je ne suis pas beaucoup plus avancé depuis le retour des profs, voici ce que je dois faire :
 // supprime un thème.
 // si l'identifiant reçu en paramètre correspond à un thème stocké, celui-ci est supprimé et elle renvoie 1.
 // si l'identifiant reçu en paramètre ne correspond à aucun thème stocké, elle renvoie 0.
 int supprimerTheme(int identifiant);

 // supprime tous les thèmes stockés.
 // renvoie le nombre de thèmes qui ont été supprimés.
 int supprimerTousLesThemes();


Voilà les tests que je dois passer :
void test_supprimer_theme1()
{
    int nbEfface = supprimerTheme(theme1.identifiant);
    TEST_ASSERT_EQUAL(1, nbEfface);
    TEST_ASSERT_EQUAL(2, nombreThemes());
}

void test_supprimer_theme4()
{
    int nbEfface = supprimerTheme(4);
    TEST_ASSERT_EQUAL(0, nbEfface);
    TEST_ASSERT_EQUAL(2, nombreThemes());
}

void test_supprimer_theme3()
{
    int nbEfface = supprimerTheme(theme3.identifiant);
    TEST_ASSERT_EQUAL(1, nbEfface);
    TEST_ASSERT_EQUAL(1, nombreThemes());
}

void test_supprimer_theme2()
{
    int nbEfface = supprimerTheme(theme2.identifiant);
    TEST_ASSERT_EQUAL(1, nbEfface);
    TEST_ASSERT_EQUAL(0, nombreThemes());
}

void test_supprimer_tous_les_themes()
{
    ajouterTheme(theme1);
    ajouterTheme(theme2);
    ajouterTheme(theme3);
    TEST_ASSERT_EQUAL(3, nombreThemes());
    int nbThemesSupprimes = supprimerTousLesThemes();
    TEST_ASSERT_EQUAL(3, nbThemesSupprimes);
    TEST_ASSERT_EQUAL(0, nombreThemes());
}


Et voici mon code :
int supprimerTheme(int identifiant)
{
    char vide='\0';
    int i=0;
    if ((identifiant>0) && (identifiant<nbThemes))
    {
        i=identifiant-1;
        if (themes[i].identifiant==identifiant)
        {
            for(i;i<nbThemes-2;i++)
            {
                themes[i].identifiant=themes[i+1].identifiant;
                strcpy(themes[i].libelle,themes[i+1].libelle);
            }
        themes[nbThemes-1].identifiant=0;
        strcpy(themes[nbThemes-1].libelle,vide);
        nbThemes--;
        return (1);
    }
    else return(0);
}

int supprimerTousLesThemes()
{
    int nbThemesDel=0;
    char vide='\0';
    themes[nbThemes-1].identifiant=0;
    strcpy(themes[nbThemes-1].libelle,vide);
    for(i=nbThemes-2;i>=0;i--)
    {
        themes[i].identifiant=themes[i+1].identifiant;
        strcpy(themes[i].libelle,themes[i+1].libelle);
        nbThemesDel++;
    }
    nbThemes=0;
    return (nbThemesDel);
}

Et voilà les erreurs que j'ai :


Donc, voilà j'ai modifié plusieurs fois mon code sans succès, je sais pas quoi faire...
0
yg_be Messages postés 23405 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 20 décembre 2024 1 557
2 mars 2019 à 17:15
il n'est pas possible de vérifier ton code sans savoir ce que fait ajouterTheme().
0
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019
2 mars 2019 à 18:17
voilà le code de la fonction ajouterTheme
int ajouterTheme(struct Theme theme)
{
    nbThemes=nombreThemes();
    theme.identifiant=nbThemes++;
    return theme.identifiant;
    nbThemes++;
}


Et ce qu'elle doit faire :
 // ajoute un theme.
 // cette fonction doit affecter un identifiant au thème reçu en paramètre.
 // elle renvoie l'identifiant affecté au thème.
 // si table est pleine, elle renvoie 0.
 int ajouterTheme(struct Theme theme);
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié le 2 mars 2019 à 23:35
D'après le code que tu as fourni, les thèmes sont stockés dans le tableau theme :

#define NB_THEMES_MAX 100

struct Theme {
    int identifiant;
    char libelle[50];
};
static struct Theme themes[NB_THEMES_MAX];
static int nbThemes=0;

L'implémentation de ajouterTheme() que tu reproduis en réponse à la question de yg_be n'ajoute pas le thème passé en paramètre au tableau themes.

A mon sens, elle est fausse.

De plus, elle confond l'identifiant correspondant à un libellé et le nombre actuel de thèmes, ce qui n'a rien à voir. Un identifiant est, par définition unique. Si tu ajoutes 2 thèmes et que tu retires le premier, et que en ajoutes un autre, nbThemes passera successivement de 0 à 1, 2, puis 1, puis 2. On voit bien que ces chiffres ne peuvent pas servir à identifier un libellé de façon unique. Si plusieurs libellés portent le même identifiant, lorsque tu voudras supprimer un libellé par son identifiant, tu ne sauras pas ce que tu supprimes.

Avant, ton code confondait identifiant de libellé et index de tableau... maintenant celui-ci confond identifiant de libellé et nombre de libellés...

Au lieu de toute cette confusion, vous pourriez vous forcer :
- à utiliser des entiers supérieurs à 100 comme identifiants
- à générer ces nombres aléatoirement
- à vérifier, avant d'utiliser le nombre généré aléatoirement, que celui-ci n'a pas déjà été utilisé pour un identifiant existant
0
Natsuko410 Messages postés 32 Date d'inscription samedi 23 février 2019 Statut Membre Dernière intervention 11 mai 2019 > [Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024
4 mars 2019 à 14:06
Moi, j'veux bien faire comme vous me le dites mais je suis obligé de suivre ce qu'on me demande, et de plus ce n'est absolument pas moi qui gère les autres fonctions, j'ai été affecté aux fonctions supprimerTheme et supprimerTousLesThemes, et j'ai beau parler au chef du groupe, il n'en démord pas. Il ne veut pas changer sa manière de fonctionner, du coup j'dois trouver un moyen de faire ce que les fonctions doivent faire en suivant la marche du groupe...
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié le 4 mars 2019 à 16:25
L'idée d'utiliser des entiers aléatoires était juste une idée frappante pour marquer les esprits sur le fait que l'identifiant n'est pas l'index, ni le nombre d'éléments. Cela peut être n'importe quoi qui soit un entier unique par rapport aux autres identifiants existants et soit différent de 0, et si je comprend bien l'exercice, tu n'as pas à savoir exactement comment il est attribué, cette information devrait t'être cachée.

D'où vient le code de ajouterTheme() que tu reproduis en réponse à la question de yg_be ? Il est évident pour moi que cette implémentation n'ajoute pas le thème passé en paramètre au tableau themes.

Et si rien n'est ajouté ... tu ne peux pas supprimer ce qui n'y est pas.
0