wxDev.fr, le portail francophone consacré à wxWidgets ! ( The french portal for wxWidgets )  
Esp. membre
Recheche rapide



Recherche avancée
Statistiques
Membres inscrits :2359

Membres en ligne : 0
Invités en ligne : 2

Valid XHTML 1.0 Transitional

Valid CSS2

Menu forum (navigation):
Pages: 1  
 
Accueil » Accueil forums » Utilisation générale wxWidgets
» Est-ce possible de faire une calculs d'un wxWtring Ex: (34+5)/3*21-3?
Conversation : Est-ce possible de faire une calculs d'un wxWtring Ex: (34+5)/3*21-3?
30-01-2013 13:54:00  Est-ce possible de faire une calculs d'un wxWtring Ex: (34+5)/3*21-3? #1
ajm (Membre)
Inscrit le : 16-03-2011
Messages: 82
Snippets: 0
Tutoriels: 0
Hors ligne
Bonjours,

Dans une wxTextCtrl l'utilisateur saisi par example "(34+5)/3*21-3" et à partir de cela qu'on calcul le resultat.

Qlq a une idée comment faire?
01-02-2013 22:18:57  Re: Est-ce possible de faire une calculs d'un wxWtring Ex: (34+5)/3*21-3? #2
Alex34 (Nouveau membre)
Inscrit le : 29-03-2010
Messages: 5
Snippets: 0
Tutoriels: 0
Hors ligne
Oui, il faut un parser qui analyse ta ligne caractère par caractère et prévoit tous les cas.
En gros, il faut des appels récursifs pour les chaines entre ( et ), ce qui n'est pas simple... surtout si tu veux gérer des chaines alpha...
Je viens de terminer le mien pour un éditeur d'état avec scripts.
C'est un gros boulot.
Juste pour te donner une idée du "moteur":

Code Cpp:

 
agVariant Parser::str2val(const wxString s)
{
    const char* p1 = s.c_str();
    agVariant result;     // mis à null !
    short i = 0;
    short imax = s.Len();
    while(i<imax && ! m_abort && p1)
    {
        int reste = imax - i;
        //wxLogMessage("Parse %s",s.Mid(i));
 
        /// recherche de mots-clés
        // d'abord mot de 6 caractères
        if (reste>=6)
        {
            const wxString op = s.Mid(i,6).Lower();
            if (op=="bitand") return result & str2val(s.Mid(i+6));
            else if (op=="bitxor") return result ^ str2val(s.Mid(i+6));
        }
        else if (s.Mid(i,5).Lower()=="bitor") return result | str2val(s.Mid(i+5));
        else if (reste>=3)
        {
            const wxString op = s.Mid(i,3).Lower();
            if (op=="and") return agVariant(result.boolAnd(str2val(s.Mid(i+3))));
            else if (op=="xor") return agVariant(result.boolOr(str2val(s.Mid(i+3))));
            else if (op=="mod") return result % str2val(s.Mid(i+3));
        }
        // puis opérateurs sur 2 caractères
        else if (reste>=2)
        {
            const wxString op = s.Mid(i,2);
            /*            if (op=="+=") return result += str2val(s.Mid(i+2));
                        else if (op=="-=") return result -= str2val(s.Mid(i+2));
                        else if (op=="*=") return result *= str2val(s.Mid(i+2));
                        else if (op=="/=") return result /= str2val(s.Mid(i+2));
                        else if (op=="%=") return result %= str2val(s.Mid(i+2));
                        else if (op=="&=") return result &= str2val(s.Mid(i+2));
                        else if (op=="|=") return result |= str2val(s.Mid(i+2));
                        else if (op=="^=") return result ^= str2val(s.Mid(i+2));
                        else */

            if (op==">=") return result.MakeBool(result >= str2val(s.Mid(i+2)));
            else if (op=="<=") return result.MakeBool(result <= str2val(s.Mid(i+2)));
            else if (op=="==") return result.MakeBool(result == str2val(s.Mid(i+2)));
            else if (op=="<>" || op=="!=") return result.MakeBool(result != str2val(s.Mid(i+2)));
            else if (op=="&&") return result.MakeBool(result.boolAnd(str2val(s.Mid(i+3))));
            else if (op=="||") return result.MakeBool(result.boolOr(str2val(s.Mid(i+3))));
        }
        /// selon début chaine...
        char c = s[i];
        /// Recherche de constante numérique
        if (isdigit(c)) result.Create(GetIdentifier(s,i, imax));
        /// Recherche d'identifiants
        else if (c=='_' || isalpha(c))
        {
            wxString s1 = GetIdentifier(s,i, imax);
            if (getNextCar(s,i,imax)=='(')
            {
                wxString s2 = GetIntricatedString(s, i, imax, ')');
                /// get parameters from (blabla,blabla)
                t_liste_parametres l;
                short k = 0; // sauter le (
                short kmax = s2.Len();
                while (k<kmax)
                {
                    wxString s3 = GetUntil(s2,k,kmax,',');
                    l.push_back(*new agVariant(str2val(s3)));
                }
                result.Assign(OnFunction(s1,l));
                if (result.IsNull())
                {
                    if (pt_OnFunction) result.Assign(pt_OnFunction(s1,l));
                    else
                    {
                        wxLogError(_("Ooops ! %s(%s) is Klingon for me"),s1,s2);
                        Abort();
                    }
                }
            }
            /// not xxx(yy,yy,yy..) , so must be identifier
            else
            {
                result.Assign(OnGetValue(s1));
                if (result.IsNull())
                {
                    if (pt_OnGetValue)  result = pt_OnGetValue(s1);
                    else
                    {
                        wxLogError(_("Ooops ! %s is Klingon for me"),s1);
                        Abort();
                    }
                }
            }
        }
        /// Sauter les blancs
        else if (isspace(c)) i++;
        /// Recherche de constantes ou d'opérateurs
        else switch (c)
            {
            case '+':
                if (result.IsNull()) result.Assign(str2val(s.Mid(i+1)));
                else return result + str2val(s.Mid(i+1));
            case '-':
                return result - str2val(s.Mid(i+1));
            case '/':
                return result / str2val(s.Mid(i+1));
            case '*':
                return result * str2val(s.Mid(i+1));
            case '%':
                return result % str2val(s.Mid(i+1));
            case '&':
                return result & str2val(s.Mid(i+1));
            case '|':
                return result | str2val(s.Mid(i+1));
            case '!':
                return !str2val(s.Mid(i+1));
            case '~':
                return ~str2val(s.Mid(i+1));
            case '>':
                return result.MakeBool(result > str2val(s.Mid(i+1)));
            case '<':
                return result.MakeBool(result < str2val(s.Mid(i+1)));
            case '=':
                return result.MakeBool(result == str2val(s.Mid(i+1)));
            case '(':
                result = str2val(GetIntricatedString(s, i, imax, ')'));
                break;
            case CHAR_BEGIN_VAR:
                result.Assign(str2val(GetIntricatedString(s, i, imax, CHAR_END_VAR)));
                break;
            case '\'':
                result.Create(GetQuotedString(s,i, imax));
                break;
            case '\"':
                result.Create(GetDQuotedString(s,i, imax));
                break;
                /*            case ttInt:
                            case ttFrac:
                            case ttRound:
                            case ttStr:
                            case ttNot:*/

            default:
                PARSE_ERROR(_("Can't recognize '%c'"),c);
                Abort();
                break;
            }
    }   // while (i<imax)
    return result;
}
 
bool ContainsOneOf(const wxString s, const wxString& rch)
// use to detect printf parameters
{
    for (unsigned i=0; i<s.Len(); i++)
        for(unsigned j=0; j<rch.Len(); j++) if (s[i]==rch[j]) return true;
    return false;
}
 
 
01-02-2013 23:44:31  Re: Est-ce possible de faire une calculs d'un wxWtring Ex: (34+5)/3*21-3? #3
Xaviou (Administrateur)
Lieu: Annecy (74)
Inscrit le : 27-08-2007
Messages: 1375
Snippets: 25
Tutoriels: 6
Site web
Hors ligne
Salut.

Je me souvenais d'avoir vu un truc très simple (mais ne fonctionnant que sous Windows).
Je l'ai enfin retrouvé.

En fait, cette astuce consiste à appeler le moteur d'évaluation javascript.

Voici l'adresse : http:/www.cppfrance.com/codes/EVAL-EXPR … 54335.aspx

Je le répète : ça ne fonctionne que sous Windows, mais çapeut toujours servir...

@+
Xav'

Le nouveau portail wxWidgets francophone : www.wxdev.fr
Ben en fait, vous y êtes déjà...
04-02-2013 08:55:46  Re: Est-ce possible de faire une calculs d'un wxWtring Ex: (34+5)/3*21-3? #4
ajm (Membre)
Inscrit le : 16-03-2011
Messages: 82
Snippets: 0
Tutoriels: 0
Hors ligne
Merci pour votre reposes, je vais les regarder.

Je vous informerais le resultat.
Menu forum (navigation):
Pages: 1  
 
Accueil » Accueil forums » Utilisation générale wxWidgets
» Est-ce possible de faire une calculs d'un wxWtring Ex: (34+5)/3*21-3?