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

C++Builder Discussion :

switch avec AnsiIndexStr [Non suivi]


Sujet :

C++Builder

  1. #1
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut switch avec AnsiIndexStr
    Bonsoir,

    Petite question nocturne....

    Je fais un switch sur des AnsiString avec l'astuce du AnsiIndexStr, décrite par ailleurs ici:

    http://c.developpez.com/faq/bcb/?pag...itchansistring


    Tout est marche pour le mieux, j'ai d'ailleurs retesté dans un précédant projet codé sur la même machine mais dans le projet en cours, impossible d'utiliser ce AnsiIndexStr...

    Qq lignes de code :
    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
     
    AnsiString ListeFixe[5] = {"ID", "FAM", "SFAM", "NOM", "UCOT"};
    String NomFourn;
    for (int i = 0; i < frmMercu->pListChamp->Count; i ++)
    {
    NomFourn = frmMercu->pListChamp->Strings[i].SubString( (frmMercu->pListChamp->Strings[i].AnsiPos("=") + 1), frmMercu->pListChamp->Strings[i].Length() );
            switch (AnsiIndexStr(NomFourn, &ListeFixe[0], 5))
            {
            case 0:  //ID
     
            break;
            case 1: //FAM
     
            break;
            case 2: //SFAM
     
            break;
            case 3: //NOM
     
            break;
            case 4: //UCOT
     
            break;
            default:
            ShowMessage("ok");
            break;
            }
    }
    J'ai bien inclus StrUtils.hpp et le tout compile correctement mais plante a l'execution.
    En ayant fait qq test, il semble que ce soit l'AnsiIndexStr qui bloque.

    J'espère, quitte a être ridicule, avoir oublié quelquechose de simplissime quelquepart plutôt que de tomber sur un souci mystérieux, comme le coup de la référence aux composants DBADO qui sautent a chaque ouverture de l'EDI :

    http://www.developpez.net/forums/viewtopic.php?t=470191


    Merci d'avance pour vos lumières...
    @ +

  2. #2
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Question supplémentaire, en rapport tout de même avec la première intérrogation :
    lorque je consulte l'aide dans builder au sujet des fonctions telles que
    AnsiIndexStr, AnsiIndexText, AnsiMatchStr, j'obtiens ces prototypes :
    extern PACKAGE int__fastcall AnsiIndexText(const AnsiString AText, const AnsiString ASubText);

    extern PACKAGE int__fastcall AnsiIndexStr(const AnsiString AText, const AnsiString ASubText);

    extern PACKAGE int__fastcall AnsiMatchStr(const AnsiString AText, const AnsiString ASubText);
    alors qu'a l'écriture ces fonctions semblent attendre les paramètres suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (AnsiString AText, const AnsiString * AValues, int AValues_size)


    Bonne nuitée,
    @ +

  3. #3
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    J'ai repris ton code dans un projet console et tout fonctionne nickel chez moi. As-tu essayé déjà comme ça?

    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
    //---------------------------------------------------------------------------
     
    #include <vcl.h>
    #include <StrUtils.hpp>
    #pragma hdrstop
     
    //---------------------------------------------------------------------------
     
    #pragma argsused
    int main(int argc, char* argv[])
    {
     
    if (argc==1) {
      return 0;
    }
     
      AnsiString ListeFixe[5] = {"ID", "FAM", "SFAM", "NOM", "UCOT"};
      String NomFourn;
      NomFourn = argv[1];
     
      switch (AnsiIndexStr(NomFourn, &ListeFixe[0], 5)) {
        case 0:  //ID
          ShowMessage("0=ID");
          break;
        case 1: //FAM
          ShowMessage("1=FAM");
          break;
        case 2: //SFAM
          ShowMessage("2=SFAM");
          break;
        case 3: //NOM
          ShowMessage("3=NOM");
          break;
        case 4: //UCOT
          ShowMessage("4=UTOC");
          break;
        default:
          ShowMessage("Default");
          break;
      }
      return 0;
    }
    //---------------------------------------------------------------------------

  4. #4
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonjour,

    Hé bien non, effectivement mais je vais le tester ainsi dès que j'ai 5 minutes.
    Merci

  5. #5
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonjour,

    Oui, en mode console le test fonctionne (j'obtiens le message correspondant au cas 'Default')...

    Que dois - je en tirer comme conclusion pour la suite ?

    Merci

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Hello

    Ca plante, ok, mais avec quel message d'erreur ??

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Points : 446
    Points
    446
    Par défaut
    Il doit y avoir un problème de contexte...

    As-tu essayé d'utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    switch (AnsiIndexStr(NomFourn, &ListeFixe, 5))
    à la place de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    switch (AnsiIndexStr(NomFourn, &ListeFixe[0], 5))

  8. #8
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonjour,

    . pour totoche76 :
    l'erreur annoncée est 'violation d'accès....lecture de l'addresse FFFFFFF' (il est devenu bègue ? )

    . pour Patrick Seuret :
    je viens d'essayer avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    switch (AnsiIndexStr(NomFourn, &ListeFixe, 5))
    mais il plante en invoquant une erreur par rapport aux paramètres attendus.
    A lire cette erreur telle qu'il l'annonce a ce moment, j'ai l'impression qu'il se met dans le contexte d'une fonction ayant pour argument :
    AnsiIndexStr(const AnsiString AText, const AnsiString ASubText);
    et non
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (AnsiString AText, const AnsiString * AValues, int AValues_size)
    ce qui me renvoie un peu a ma question sur les prototytes des fonctions AnsiIndexStr, AnsiIndexText, ...et cie.

    En tout cas, merci déja pour votre intérêt a mon égard....

    @ +

  9. #9
    Membre éclairé
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Points : 785
    Points
    785
    Par défaut
    Au fait l'utilisation de cette fonction allourdi les performances du soft.

    Dans le pire des cas, on aura parcouru N éléments, et ensuite on se permet de refaire un switch sur des valeurs numériques.

    La solution proposée ce-dessous permet de gagner en temps d'exécution.

    1) Il serait utile d'employer un static std::set< AnsiString > qui ne contiendrait que la liste des éléments.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    static std::set< AnsiString > lstElements;
    if (lstElements.empty()) {
        // ajouter les éléments.
    }
     
    // pour retrouver un élément
    if (lstElements.find("toto") != lstElements.end()) {
        // On a trouvé l'élément
    } 
    else {
        // On n'a pas trouvé l'élément
    }
    Maintenant si il faut un container associatif, autant employer une std::map.

  10. #10
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonsoir,

    Merci swirtel,
    Effectivement, dis comme ça, ça parait si simple....suffisait d'y penser.

    Ca me plait bien moi ce petit bout de code

    Néanmoins, j'aimerais bien comprendre le pourquoi de ce blocage sur le switch, alors qu'il ne l'a pas bloqué pour un projet d'un genre similaire sur la même machine.

    Merci,
    @ +

  11. #11
    Membre éclairé
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Points : 785
    Points
    785
    Par défaut
    Ton erreur provient du second argument, c'est un pointeur, tout ce qu'il attend c'est l'adresse du tableau. En C et C++, l'adresse d'un tableau est représenté par le nom de la variable de type array.

    Dans ton cas, il s'agit de "ListeFixe". Ce qui donnera.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    static AnsiString ListeFixe[] = {"ID", "FAM", "SFAM", "NOM", "UCOT"};
    static unsigned int sizeListeFixe = sizeof(ListeFixe)/sizeof(ListeFixe[0]);
     
    switch( AnsiIndexStr( NomFourn, ListeFixe, sizeListeFixe ) ) {
    /// ma suite de case
    /// ne pas oublier le default
    }

  12. #12
    Membre éclairé
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Points : 785
    Points
    785
    Par défaut
    En gros, si tu comparles AnsiIndexStr, sa complexité est de maximum O(n). Ce qui est énorme.

    Alors qu'avec une std::map, ou une std::set, tu seras en moyenne en temps constant (=~ O(1)).

  13. #13
    Membre expert
    Avatar de Sunchaser
    Homme Profil pro
    OPNI (Objet Programmant Non Identifié)
    Inscrit en
    Décembre 2004
    Messages
    2 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : OPNI (Objet Programmant Non Identifié)
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 059
    Points : 3 204
    Points
    3 204
    Par défaut
    Bonjour,

    Merci swirtel pour cette suite,

    Malgré tout, l'AnsiIndexStr ne passe toujours pas (comme je le soupçonnais un peu) alors que, comme je le répète a mon grand étonnement, je n'ai aucun souci avec lui ou ses cousins dans un projet antérieur sur le même PC.

    Merci pour la suite des conseils...

  14. #14
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Citation Envoyé par Cantrelle
    Question supplémentaire, en rapport tout de même avec la première intérrogation :
    lorque je consulte l'aide dans builder au sujet des fonctions telles que
    AnsiIndexStr, AnsiIndexText, AnsiMatchStr, j'obtiens ces prototypes :
    extern PACKAGE int__fastcall AnsiIndexText(const AnsiString AText, const AnsiString ASubText);

    extern PACKAGE int__fastcall AnsiIndexStr(const AnsiString AText, const AnsiString ASubText);

    extern PACKAGE int__fastcall AnsiMatchStr(const AnsiString AText, const AnsiString ASubText);
    alors qu'a l'écriture ces fonctions semblent attendre les paramètres suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (AnsiString AText, const AnsiString * AValues, int AValues_size)


    Bonne nuitée,
    @ +
    Bonjour,

    Sans pouvoir t'aider sur ton problème précis, je peux commenter ce problème de prototypes.

    Les prototypes de l'aide sont les prototypes de la version Delphi. Or en C++, on n'a pas moyen de connaître la taille d'un tableau juste à partir de son pointeur, et donc on doit fournir sa taille.

    Sinon je confirme la lourdeur de cette fonction, qui a néanmoins le mérite d'exister, et qui, dans une application Windows classique où somme toute les temps de traitements sont infimes par rapport aux temps d'attente d'actions de l'utilisateur, ne devrait pas poser problème. Si l'application a des contraintes d'optimisation, en revanche, il est effectivement intéressant d'envisager une autre solution.

    Cordialement,

    Arnaud

Discussions similaires

  1. 'switch' avec du String
    Par schousso dans le forum Langage
    Réponses: 12
    Dernier message: 07/07/2015, 14h27
  2. switch avec plusieurs arguments
    Par lazzeroni dans le forum Langage
    Réponses: 4
    Dernier message: 18/07/2006, 13h34
  3. pb connexion switch avec .bat
    Par bessonnet dans le forum Windows
    Réponses: 8
    Dernier message: 23/06/2006, 20h12
  4. Switch avec des variables
    Par Reven777 dans le forum C++Builder
    Réponses: 6
    Dernier message: 19/05/2006, 13h30
  5. comment faire switch avec des strings ?
    Par ilimo dans le forum C++
    Réponses: 2
    Dernier message: 18/04/2006, 21h08

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