الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيفية تحويل نص يحتوي على عمليات حسابية

بدأه نادين01 في 23 نوفمبر 2013 · 9 رد · 829 مشاهدة · في ارشيف قسم C/C++
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله تعالى وبركاته

 

انا عضوة جديدة معكم في المنتدى ، أتمنى ان تقبلوني بينكم

 

انا مبتدئة في البرمجة بلغة c واريد مساعدتكم

 

اريد معرفة ان كانت توجد دالة تقوم بتحويل نص الى اعداد حقيقة (لكن في النص يوجد حتى + - * /) ، اي يمكنها التمييز بين الاعداد والعمليات

تم تعديل هذه المشاركة بواسطة نادين01 في 24 نوفمبر 2013 في 00:27

#2

و عليكم السلام

 

أهلا بك في منتديات الفريق العربي للبرمجة, أظن أنك نفس العضوه التي أجبتها قبل ساعات في منتديات developpez, صح ؟ :)

 

بالنسبة لسؤالك فإذا كنتِ تُريدين كتابة كود يقوم بحساب نتيجة عملية حسابية يتم تمريرها كنص فأعتقد أنه لا توجد دالة جاهزة لمثل هذا الأمر.

عموماً, هذا parser صغير, قد يُفيدك :

#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>

/**
 *
 * @author Sn@CkeR
 */

typedef enum fn_id {
    bad_id, sin_id, cos_id
} fn_id;

double eval_factor(char const* exp, char const** end);
double eval_term(char const* exp, char const** end);
double eval_exp(char const* exp, char const** end);

int error_occured = 0;

void error(char const* msg, char const* remainder) {
    if (!error_occured) {
        printf("%s at: %s\n", msg, remainder);
        error_occured = 1;
    }
}

char const* skipws(char const* exp) {
    while (isspace((int) (unsigned char) *exp)) {
        exp++;
    }
    return exp;
}

fn_id getfn(char const** x) {
    if ((*x)[0] == 's' && (*x)[1] == 'i' && (*x)[2] == 'n' && !isalpha((*x)[3])) {
        (*x) += 3;
        return sin_id;
    } else if ((*x)[0] == 'c' && (*x)[1] == 'o' && (*x)[2] == 's' && !isalpha((*x)[3])) {
        (*x) += 3;
        return cos_id;
    } else {
        error("Bad function name", *x);
        while (isalpha(**x)) {
            ++(*x);
        }
        return bad_id;
    }
}

double eval_factor(char const* exp, char const** end) {
    double result;
    exp = skipws(exp);
    if (*exp == '(') {
        result = eval_exp(exp + 1, end);
        if (**end != ')') {
            error("missing closing parenthesis", *end);
        } else {
            ++*end;
        }
    } else if (*exp == '+') {
        result = eval_factor(exp + 1, end);
    } else if (*exp == '-') {
        result = -eval_factor(exp + 1, end);
    } else if (isalpha(*exp)) {
        switch (getfn(&exp)) {
            case sin_id:
                result = sin(eval_factor(exp, end));
                break;
            case cos_id:
                result = cos(eval_factor(exp, end));
                break;
            case bad_id:
                break;
        }
    } else {
        char* endptr;
        result = strtod(exp, &endptr);
        *end = endptr;
        if (*end == exp) {
            error("invalid number", *end);
        }
    }
    return result;
}

double eval_term(char const* exp, char const** end) {
    double result = eval_factor(exp, end);
    *end = skipws(*end);
    while (**end == '*' || **end == '/') {
        char const* op = *end;
        double factor = eval_factor(*end + 1, end);
        if (*op == '*') {
            result *= factor;
        } else if (factor != 0.0) {
            result /= factor;
        } else {
            error("divide by 0.0", op);
        }
        *end = skipws(*end);
    }
    return result;
}

double eval_exp(char const* exp, char const** end) {
    double result = eval_term(exp, end);
    *end = skipws(*end);
    while (**end == '+' || **end == '-') {
        char const* op = *end;
        double term = eval_term(*end + 1, end);
        if (*op == '+') {
            result += term;
        } else {
            result -= term;
        }
        *end = skipws(*end);
    }
    return result;
}

double eval(char const* exp) {
    char const* end;
    double result = eval_exp(exp, &end);
    if (*end != '\0') {
        error("trailing data after the expression", end);
    }
    return result;

}

int main() {
    error_occured = 0;
    char const* exp = "((2*6)+9*(7+3)-5)/6 + sin(4)";
    double result = eval(exp);
    if (!error_occured)
        printf("%s = %.20g\n", exp, result);
    return 0;
}

تحياتي.

تم تعديل هذه المشاركة بواسطة Snack3r في 24 نوفمبر 2013 في 00:37

3
#3

شكرا لك اخي الكريم

بالفعل انا نفس العضوة ، لكن المنتدى الاخر تصعب علي المشاركة فيه وهذا لعدم تمكني من اللغة الفرنسية

والحمد لله اليوم تعرفت على هذا المنتدى الرائع

#4

أهلا بك (لا أخفيك سراً, أنه يلزمك تعلم إحدى اللغات الأجنبية لمواصلة تعلم البرمجة :) )

 

هل تمت الإجابة على سؤالك ؟

تم تعديل هذه المشاركة بواسطة Snack3r في 24 نوفمبر 2013 في 00:54

#5

كلامك صحيح اخي الكريم يجب تعلم اللغات خصوصا الانجليزية

 

صراحة انا مبتدئة في البرمجة ولهذا برنامجك معقد نوعا ما ( لم يكن لي الوقت الكافي لفهمه لكن لي عودة له ان شاء الله)

#6

أختي برنامج الأستاذ Snack3r متقدم .. فهو Parser أي محلل نحوي للعمليات الحسابية ..

هل ما تسألين عنه هو واجب في الجامعة مثلاً ؟ لأنه لا بد أن يكون أبسط من هذا الحل ..

--- أرجو الرد في أسرع وقت ---

#7

نعم هو واجب جامعي طلب منا ادخال عمليات حسابية على شكل postfixée ( بدون sin و cos)

#8
#include <stdio.h>#include <stdlib.h>#include<string.h>#include<conio.h>/* Déclaration de Type*/   typedef struct S_ElementPile {		float  info;		struct S_ElementPile* suivant;		} Elementpile;		/* Variables Globales*/   int  Choix;	 /* choix de menu*/    char* v,s;   Elementpile* sommet; ,float x,r,y;void empiler( float r ) {     Elementpile* nelement;             nelement = malloc(sizeof(Elementpile));      nelement->info= r;	if(sommet== NULL) {  	     sommet=nelement;	     sommet->suivant=NULL;               }  else{               nelement->suivant=sommet;      sommet=nelement;                }        getch();	  }	  	  float  depiler() {Elementpile* nouv;float l;							  nouv = sommet;				  l= nouv->info;				  sommet=nouv->suivant;				  free(nouv);				  			        getch();   return (l);    }void main (){     int i=1;printf(" donner la chaine");scanf("%",&v);while (i <= strlen(v) ){ if( v== '+')  { x=depiler ();        y=depiler ();               empiler (x+y); i++;}   else{    if( v== '-') { x=depiler ();          y=depiler ();       empiler (y-x);i++;}      else{         if( v== '*') { x=depiler ();          y=depiler ();       empiler (x*y);i++; }           else{             if( v== '/') { x=depiler ();          y=depiler ();       empiler (y/x);i++;}             else{                if ( v== '#')  i++; else {                   s= ' ' ;}                   while (v != '#'){s=s+ v; i++;}empiler (atof (s));  }printf ("resultat eslt:%f", depiler ());}

اين الخطأ في البرنامج بحيث بين كل عدد او عملية يكون #

تم تعديل هذه المشاركة بواسطة نادين01 في 28 نوفمبر 2013 في 23:09

#9
  • وضّحي السؤال أكثر من فضلك .. ما هو الدخل المطلوب وما هو الخرج المطلوب ؟ ماهي المشكلة ؟
  • ولا داعي لفتح موضوع جديد طالما هذا الموضوع موجود

    بالتوفيق

#10

La  notation postfixee qui consiste a rentrer les operandes
puis les operateurs s'appliquant sur ceux-ci.
Par exemple, l'operation: (3*11+5)/(27*3-5) sera tapee dans l'ordre suivant:
 / - 5  * 3 27 + 5 * 11 3
Cette notation ne necessite pas de parentheses. L'utilisation d'une pile permet de programmer
facilement une calculatrice fonctionnant sur ce principe

لكن عند الادخال ندخل بين كل caractere #

 

اي

 /# -# #5  *# #3 #2#7 +# #5 *# #1#1 3

تم تعديل هذه المشاركة بواسطة نادين01 في 29 نوفمبر 2013 في 12:16

−1

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…