IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

GTK+ avec C & C++ Discussion :

Numerotation automatique de sections


Sujet :

GTK+ avec C & C++

  1. #1
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut Numerotation automatique de sections
    Bonjour,

    J'essais de mettre en place une numérotarion automatique de section d'un fichier XML. Le but est de calculer le prochain ID de la section du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <section id="I">
      <section id="I-A">
      </section>
      | <!-- Le curseur -->
    </section>
    Si l'utilisateur demande une nouvelle section au niveau du curseur, la fonction section_next_id doit me retourner la chaîne "I-B".

    Voici ce que j'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    static char *section_id[4][5] =
    {
      {"I", "II", "III", "IV", NULL},
      {"A", "B", "C", "D", NULL},
      {"1", "2", "3", "4", NULL},
      {NULL, NULL, NULL, NULL, NULL}
    };
     
    static char *section_sep = "-";
     
    static gchar *section_next_id (GtkTextBuffer *p_buffer)
    {
      gint niveau = 0;
      gint sous_niveau = 0;
      gchar *ret = NULL;
      gchar *section = NULL;
     
      if (p_buffer)
      {
        gint line = 0;
        GtkTextIter iter;
        GtkTextIter match_start;
        GtkTextIter match_end;
     
        /* On recupere la position du curseur */
        gtk_text_buffer_get_iter_at_mark (p_buffer, &iter, gtk_text_buffer_get_insert (p_buffer));
        /* On la sauvegarde la ligne courrante */
        line = gtk_text_iter_get_line (&iter);
        /* Recuperation du texte *" dans <section id="*"[ noNumber=1]> */
        if (gtk_text_iter_backward_search (&iter, "<section id=\"",
              GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &match_start, NULL)
            && gtk_text_iter_forward_search (&match_start, "\"",
                   GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &match_end, NULL))
        {
          gchar **sections = NULL;
     
          section = gtk_text_buffer_get_slice (p_buffer, &match_start, &match_end, FALSE);
          /* Suppression du guillement en trop */
          section[g_strlen (section)-1] = '\0';
          sections = str_split (section, section_sep);
          if (sections)
          {
            /* Calcul du niveau de la balise precedente puisque le tableau se termine par NULL */
            while (sections[niveau])
            {
              niveau++;
            }
            {
              GtkTextIter *p_iter = NULL;
     
              /* On se place apres l'id de la section precedente */
              p_iter = gtk_text_iter_copy (&match_end);
              /* Calcul le niveau de la nouvelle balise en decomptant les balises <section> fermees */
              while (gtk_text_iter_forward_search (p_iter, "</section>",
                       GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &match_end, NULL)
                     /* on recherche jusqu'a la ligne du curseur */
                     && gtk_text_iter_get_line (p_iter) <= line)
              {
                niveau--;
                /* Au cas ou l'utilisateur a ajoute une balise fermante de trop */
                if (niveau < 0)
                {
                  niveau = 0;
                  break;
                }
                gtk_text_iter_free (p_iter); p_iter = NULL;
                p_iter = gtk_text_iter_copy (&match_end);
              }
            }
            /* Recherche de l'id suivant dans le sous-niveau */
            while (sections[niveau]
                    && section_id[niveau]
                    && section_id[niveau][sous_niveau]
                    && g_strcmp (sections[niveau], section_id[niveau][sous_niveau]) == 0)
            {
              sous_niveau++;
            }
            sma_free (sections);
          }
        }
      }
      /* niveau 0 = racine donc pas besoin de concatener les niveaux precedent */
      if (niveau > 0)
      {
        ret = g_strdup_printf ("%s%s%s", section, section_sep, section_id[niveau][sous_niveau]);
        sma_register (ret);
      }
      else
      {
        ret = g_strdup_printf ("%s", section_id[0][sous_niveau]);
        sma_register (ret);
      }
      return ret;
    }
    Ne vous occupez pas des fonctions sma_* il s'agit d'un gestionnaire de mémoire perso.

    ça marche bien pour l'ajout de la section II mais ensuite il me sort toujours "I" (aussi bien à la place de "III" ou "I-A") : il semblerai que la recherche des balises fermantes ne s'arrête pas au curseur puisque j'obtiens un niveau négatif.

    Si vous avec des remarques concernant l'algo/codage pour faire avancer le smilblick je suis prenneur

    d'avoir tenu le coup jusqu'ici

  2. #2
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Sans pouvoir trop regarder ton code, je dirais juste:

    - Tu ne déalloues pas toujours p_iter mais cela ne devrait pas avoir d'influence sur ton code

    - Ton test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     && g_strcmp (sections[niveau], section_id[niveau][sous_niveau]) == 0)
    Me semble suspect... Mais il n'aurait pas d'influence sur le mauvais compte de niveau...

    Je viens de voir ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     while (gtk_text_iter_forward_search (p_iter, "</section>",
                       GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &match_end, NULL)
                     /* on recherche jusqu'a la ligne du curseur */
                     && gtk_text_iter_get_line (p_iter) <= line)
    Ton deuxième test devrait plutôt être:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     && gtk_text_iter_get_line (math_end) <= line)
    non? Je suppose qu'il faudra aussi rajouter un test:

    avant...

    Cela expliquerait en fait le mauvais comptage de niveau...

    Jc

  3. #3
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par fearyourself
    - Tu ne déalloues pas toujours p_iter mais cela ne devrait pas avoir d'influence sur ton code
    un oubli, en effet.

    Citation Envoyé par fearyourself
    - Ton test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     && g_strcmp (sections[niveau], section_id[niveau][sous_niveau]) == 0)
    Me semble suspect... Mais il n'aurait pas d'influence sur le mauvais compte de niveau...
    Qu'est ce qui te semble bizare, dans section j'ai par exemple :
    pour la section I-A (si ça peut eclaircir l'affaire).

    Citation Envoyé par fearyourself
    Je suppose qu'il faudra aussi rajouter un test:

    avant...
    nan match_end n'est pas un pointeur.

    Bon j'ai effectué bêtement les modif que tu me propose (les nuits de sommeil sont courtes les derniers jours de projet) et ça avance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <section id="I">
      <section id="I-A">
        <section id="I-1"">
        </section>
      </section>
      <section id="I-B">
      </section>
      <section id="I-A">
      </section>
    </section>
    <section id="II">
    </section>
    <section id="I">
    </section>
    Donc ça marche sur deux niveaux, je vais essayer de voir ce qui cloche.

    Merci

  4. #4
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par gege2061
    Citation Envoyé par fearyourself
    - Ton test:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     && g_strcmp (sections[niveau], section_id[niveau][sous_niveau]) == 0)
    Me semble suspect... Mais il n'aurait pas d'influence sur le mauvais compte de niveau...
    Qu'est ce qui te semble bizare, dans section j'ai par exemple :
    pour la section I-A (si ça peut eclaircir l'affaire).
    Je dis que cela me semble suspect parce que:

    Supposons que sections = { "I" , "B" }.

    On va aussi supposer que l'entier niveau est correctement calculé et donc vaut 1 au début de cette boucle.
    Ce que tu veux faire avec cette boucle c'est en fait donner la valeur 2 à l'indice sousniveau (pour que section_id[niveau][sous_niveau] -> "C")

    Donc en français, on veut que ta boucle regarde le "A", le passe (c'est pas égale au "B")
    ensuite passe au "B", s'arrête puisqu'on a trouvé! Et incrémente une dernière fois pour passer au "C" prochain indice..

    Donc finalement, (c'est vrai j'aurais pu prendre plus de temps hier), ce test,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     g_strcmp (sections[niveau], section_id[niveau][sous_niveau]) == 0)
    devrait être:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     g_strcmp (sections[niveau], section_id[niveau][sous_niveau]) != 0)
    comme ça on s'arrête lorsqu'on est au bon sousniveau.

    Ensuite, après cette boucle, incrémente une dernier fois le sousniveau pour avoir le prochain... Il faudra biensûr faire attention que section_id[niveau][sous_niveau] != NULL...

    Remarque: Une façon plus sympa de faire ta conversion serait de faire quelques fonctions...

    Genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int convert1(char * s) -> qui transforme "A" en 0, "B" en 1 ...
    int convert2(char * s) -> qui transforme "1" en 0, "2" en 1 ...
    Et ensuite tu fais une fonction générique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int convert(char *s) -> qui transforme "A" ou "1" en 0, "B" ou "2" en 1
    et des fonctions dans l'autre sens

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void invconvert1(int i, char *s) -> qui transforme 0 en "A", 1 en "B"...
    void invconvert2(int i, char *s) -> qui transforme 0 en "1", 1 en "2"...
    et biensûr la fonction inverse générique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void invconvert(int niveau, int sousniveau, char*s) -> qui fait ce qu'on veut (je fatigue!)
    Cela aurait l'inconvénient d'être un peu plus chiant à écrire mais au moment de calculer le sous-niveau ce serait plus facile et en plus les mises à jours serait plus simple...

    A la limite, c'est plus forcément la peine... Par contre, est-ce normal que dans ton exemple, tu aies "I-1" ? J'aurais plutôt pensé à "I-A-1"... Mais cela vient de comment tu génères ta chaîne à la fin...

    Si tu voulais un "I-A-1", je pense qu'il suffirait de modifier la fin de ton programme. En utilisant mes fonctions, cela deviendrait donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    //On a le niveau, calculons le sousniveau
    sousniveau = convert(sections[niveau]);
    //On l'incrémente
    sousniveau++;
    //On récupère les chaînes nécessaires dans s
    s[0]='\0';
    //On copie les premiers niveaux, logique c'est les mêmes
    for(i=0;i<niveau;i++)
       {
       strcat(s,sections[niveau]);
       strcat(s,"-");
       }
    //Dernier ajout, le dernier sousniveau
    invconvertit(niveau,sousniveau,tmp);
    strcat(s,tmp);
     
    //Voila, on a notre chaîne...

    Jc

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    ça y ai, je me suis inspiré de tes idées fearyourself (l'idée des fonctions m'a bien simplifié la vie ) et maintenant ça marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    static gchar ***get_section (void)
    {
      gint i;
      gchar ***ret = NULL;
     
      ret = sma_malloc ((NB_NIVEAU+1) * sizeof (*ret));
      for (i = 0; i < NB_NIVEAU; i++)
      {
        gchar *sz_opt = NULL;
        gchar *text = NULL;
     
        text = g_strdup_printf ("Numeros%d", i+1);
        sma_register (text);
       /* Recupere la liste des numeros, dans un fichier ini, separe par des virgules */
        sz_opt = get_value_from_config_file ("EditeurXML", text);
        sma_free (text);
        ret[i] = g_strsplit (sz_opt, ",", -1);
      }
      return ret;
    }
     
     
    gint convert (gchar ***section_id, const gchar *s)
    {
      gint ret = -1;
     
      if (s)
      {
        gint i;
        gint j;
     
        for (i = 0; i < NB_NIVEAU; i++)
        {
          for (j = 0; section_id[i][j]; j++)
          {
            if (g_strcmp (section_id[i][j], s) == 0)
            {
              ret = j;
              goto  end;
            }
          }
        }
    end :
    (void)i;
      }
      return ret;
    }
     
    static const gchar *invconvert (gchar ***section_id, gint n, gint sn)
    {
      gchar *ret = "";
     
      if (n >= 0 && sn >= 0 && n < NB_NIVEAU /*&& sn < G_N_ELEMENTS (section_id[n])*/)
      {
        ret = section_id[n][sn];
      }
      return ret;
    }
    Merci pour votre aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. aide sur la numerotation/automatique
    Par abouam dans le forum Access
    Réponses: 8
    Dernier message: 24/02/2006, 19h15
  2. Numerotation automatique
    Par mael94420 dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 16/01/2006, 02h05
  3. Probleme avec la numerotation automatique
    Par Sylk dans le forum SQL Procédural
    Réponses: 6
    Dernier message: 29/11/2005, 16h15
  4. NUMEROTATION AUTOMATIQUE CHAMP
    Par christellel198 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 21/10/2005, 12h52
  5. [xsl] numerotation automatique
    Par ed_hunter dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 07/05/2004, 11h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo