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

مشكلة التأكد من المدخلات فى برنامج أله حاسبة بسيطة

بدأه ringawy في 11 فبراير 2012 · 25 رد · 2,323 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

أواجة مشكلة فى الكود التالى عند إدخال مدخلات خاطئة فى المتغير char الذى يستقبل العملية المراد تنفيذها مثل الجمع أو الطرح تظهر تلك المشكلة الموجودة بالصورة لآنة من المفترض أن يتم سوأل المستخدم عن إعادة إختيار الدخول على الحاسبة أو الخروج من البرنامج أما الذى يحدث فإن البرنامج يقوم بإدخال إختيار الحاسبة لوحدة ثم يطبع خطأ فى إدخال أول رقم ثم يتوقف البرنامج ثانية منتظرا إختيار المستخدم للدخول على الحاسبة أو الخروج من البرنامج فما المشكلة وما الحل أسف على الإطالة

346306357.jpg

كود البرنامج بالاسفل

/*
  Name: mohamed elhababshe
  Copyright: rinGawy Team
  Author: mohamed elhabashe
  Date: 24/01/12 02:27
  Description: simpel calculator
*/
#include <limits>
#include <cstdlib>
#include <iostream>
float a,b;
int e,f,c;
using namespace std;
void Errorinput(void)
{
cout<<"-------------------------"<<endl<<"Error Enter your number again"<<endl<<"-------------------------"<<endl;
}

void Errormethod(void)
{
cout<<"-------------------------"<<endl<<"Error"<<a<<"/0 Wrong method cannot divide by zero please correct your method"<<endl<<"-------------------------"<<endl;
}

void Erroroperathion(void)
{
cout<<"-------------------------"<<endl<<"Error please Enter your operathion again"<<endl<<"-------------------------"<<endl;
}

void Erroronumber(void)
{
cout<<"-------------------------"<<endl<<"Error number input number between 1 or 2 or 3"<<endl<<"-------------------------"<<endl;
}

int main()
{
    char d;
    do{
         first:
    cout<<"hello this main menu please Enter your choice number"<<endl<<"1-Enter calculating program"<<endl<<"2-information about me"<<endl<<"3-no thanks get me out of here"<<endl<<"=>>";
    cin>>c;
    if(cin.fail()==true)
    {
    cin.clear();
    cin.ignore(std::numeric_limits<int>::max(),'\n');
    Errorinput();
    goto first;
    }
    else
    switch(c)
    {
             case 1:{
                  cout<<"welcome to my simple calculator"<<endl<<"Enter frist number =";
                  cin>>a;
                  if(cin.fail()==true)
                  {
                  cin.clear();
                  cin.ignore(std::numeric_limits<int>::max(),'\n');
                  Errorinput();
                  goto first;
                  }
                  else
                  cout<<"Enter second number =";
                  cin>>b;
                  if(cin.fail()==true)
                  {
                  cin.clear();
                  cin.ignore(std::numeric_limits<int>::max(),'\n');
                  Errorinput();
                  goto first;
                  }
                  else
                  seconde:
                  cout<<"Enter your arithmetic operathion like ( + , - , * , / ,% ) =";
                  cin>>d;
                  if(cin.fail()==true)
                  {
                  cin.clear();
                  cin.ignore(std::numeric_limits<int>::max(),'\n');
                  Erroroperathion();
                  goto seconde;
                  }
                  else

                      switch(d)
                      {
                      case '+':cout<<"------------------"<<endl<<a<<"+"<<b<<"="<<a+b<<endl<<"------------------"<<endl;break;
                      case '-':cout<<"------------------"<<endl<<a<<"-"<<b<<"="<<a-b<<endl<<"------------------"<<endl;break;
                      case '*':cout<<"------------------"<<endl<<a<<"*"<<b<<"="<<a*b<<endl<<"------------------"<<endl;break;
                      case '/':{
                           if(b==0)
                           {
                                  Errormethod();
                                  goto first;
                           }
                           else
                           cout<<"------------------"<<endl<<a<<"/"<<b<<"="<<a/b<<endl<<"------------------"<<endl;break;
                           }
                      case '%':{
                           if(b==0)
                           {
                                  Errormethod();
                                  goto first;
                           }
                           else
                           e=(int)a;
                           f=(int)b;
                           cout<<"------------------"<<endl<<e<<"%"<<f<<"="<<e%f<<endl<<"------------------"<<endl;break;
                               }
                      default:Erroroperathion();
                      }
                      };break;
               case 2:cout<<"---------------------------------"<<endl<<"my name: mohamed elhabashe"<<endl<<"my age: 25"<<endl<<"from: Egypt (country of fredoom)"<<endl<<"---------------------------------"<<endl;break;
               case 3:cout<<"bye bye see you later"<<endl;break;
               default:{
                        cin.clear();
                        cin.ignore(std::numeric_limits<int>::max(),'\n');
                  Erroronumber();
                  goto first;
                  };
               }   
}while(c!=3);
    system("PAUSE");
    return 0;
}
1
#2

فكر فى هذة الحلول حتى نتلقى:

  • أحذف عبارة goto من برنامجك واستبدلها بــ while
  • حول المتغيرات char الى string واستمتع بمميزات السي++ وأﻻ فبرنامج برنامج سي وليس ++

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#3

السلام عليكم

مرحبا اساتذتي :)

اقتباس
حول المتغيرات char الى string واستمتع بمميزات السي++ وأﻻ فبرنامج برنامج سي وليس ++

عفوا, الكود مكتوب بلغة السي++ لوجود علامات عديدة منها استخدام مساحة الأسماء std و طريقة تضمين المكتبات و استعمال الكائنين cout و cin و ...

.. أضف إلى ذلك أنه لا يمكن استخدام الفئة string في هذه الحالة لأنها غير معرفة داخل swtch :)

اقتباس
أواجة مشكلة فى الكود التالى عند إدخال مدخلات خاطئة فى المتغير char

إذا كنت تحن إلى السي فيمكنك استخدام الدالة getch أما في السي++ فيمكنك كتابة داالة خاصة بالإدخال حيث تستقبل string و تعيد char عبارة عن الحرف الأول من هذه السلسلة, عندها يمكنك استخدام نتيجة الدالة في switch.

تحياتي و ا حترامي لكما.

تم تعديل هذه المشاركة بواسطة khaled_prg في 12 فبراير 2012 في 02:46

#4

شكرا لك أخى khaled_prg وأخى محمد ابوزايد

ولكن هل لو أستخدمت دالة لإرجاع أول حرف فى السلسة هل سيحل مشكلتى فى تكرار اللوب مرتين لأنى أريد تكرارة مرة واحدة فقط

لأنى لا أظن أن الخطأ فى switch أو المتغير الحرفى

أظن أن الخطأ فى أنة يجب عمل مسح لمحتوى المتغير عند وجود خطأ حتى يسمج بإستقبال مدخلات جديدة أتمنى أكون عرفت أوصل السؤال

i need to reset the virable:-a and b

وجزاكم الله كل خير

تم تعديل هذه المشاركة بواسطة ringawy في 12 فبراير 2012 في 13:42

#5
اقتباس
الفئة string سوف تجعل عمليات المقارنة بين النصوص عملية سهلة بكثير عن امكانيات لغة سي

وعندما يدمج معها الدوارة while اعتقد ان البرنامج سوف ينقلب حالة

أعرف ذلك و لكن سيلزمه استخدام if-else بدل switch لأن الأخيرة لا تدعم سوى int و char :)

أخي ringawy, كما قال لك الأستاذ محمد أبو زايد, إذا كنت تريد كتابة كود برمجي قابل للقراءة فابتعد عن goto

إذا كنت تريد معرفة السبب, انظر هنا :

جملة Goto

اقتباس
هل لو أستخدمت دالة لإرجاع أول حرف فى السلسة هل سيحل مشكلتى فى تكرار اللوب مرتين

نعم أخي الكريم :)

تم تعديل هذه المشاركة بواسطة khaled_prg في 12 فبراير 2012 في 22:28

#6

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

أهلا بك ringawy :)

بالمناسبة, أذكر أنني وضعت لك ردا (يحتوي على العديد من النقاط التي تهمك) في الموضوع السابق, هل رأيته ؟

برنامج اله حاسبة فى بيئة الكونصول

#7

أهلا بك أخى وأستاذى أحمد الشنقيطي وشكرا لك أخى khaled_prg على المساعدة

سوف أبتعد عن goto نهائيا نظرا لأن الكل ينصحنى للأستغناء عنها

وسوف أستخدم do ,while

وأيضا وقعت فى خطأ break مرة أخرى فى الحالة default

ولم أتذكر أنا أمسح الشاشة بعد اداء العمليات أو عند تكرار اللوب

شكرا لكم أخوانى على التوجيهات المهمة ولى عودة بعد التعديلات فى الكود ومحاولة تطويرة أكثر وأتمنى أن يكون كل الاعضاء مثلكم ليمدو يد العون للمبتدئين

وأرجو من أخى أحمد محاولة إرسال كود الحاسبة خاصتة لى حتى أتعلم منة

وجزاكم الله خيرا

1
#8
اقتباس
لى عودة بعد التعديلات فى الكود ومحاولة تطويرة أكثر

+1

بانتظار الكود الجديد.

من الآن فصاعدا حاول ترقيم نسخ البرنامج مثلا النسخة الأولى باسم Mini Calc 5.9 و الثانية 6.07 و هكذا .. أيضا يُفضل أن يكون هناك ملف نصي صغير باسم LISEZMOI أو README يحتوي على كيفية استعمال البرنامج و المراحل التي مر بها البرنامج (كل مرحلة و الخصائص التي كانت تميزها).

سأتابع معك هذا المشروع حتى تنتقل إلى برمجته بالــ OOP و كتابة الشفرة في الــ GUI إن شاء الله.

اقتباس
أرجو من أخى أحمد محاولة إرسال كود الحاسبة خاصتة لى حتى أتعلم منه

أنا مستعد, سأرسل لك الكود على الخاص.

أطيب التحية.

تم تعديل هذه المشاركة بواسطة أحمد الشنقيطي في 13 فبراير 2012 في 01:34

#9
اقتباس
عند إدخال مدخلات خاطئة فى المتغير char الذى يستقبل العملية المراد تنفيذها مثل الجمع أو الطرح تظهر تلك المشكلة

قم بقراءة المحتوي المدخل من المستخدم فى متغير نصي و قم بالتحقق من ان محتواه ارقام فقط، و من ثم قم بتحويل النص إلى الرقم الذى يمثله، بهذا تتفادي هذا الخطأ.

قم بمراجعة هذا الموضوع حيث يحتوى على حل لهذه المشكله.

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#10
اقتباس
قم بقراءة المحتوي المدخل من المستخدم فى متغير نصي و قم بالتحقق من ان محتواه ارقام فقط، و من ثم قم بتحويل النص إلى الرقم الذى يمثله، بهذا تتفادي هذا الخطأ.

مرحبا بك أخي محمد :)

لا أظن أن هذا ما يريده الأخ ringawy ! لأن المُدخلات يجب ان تكون حرفية char (يتم أخذ الحرف الأول فقط, تماما كما تفعل getch في لغة السي)

احترامي لك.

تم تعديل هذه المشاركة بواسطة khaled_prg في 13 فبراير 2012 في 04:00

#11

ما يتم ببساطة فى الذاكرة كالتالى كيف نعالجة؟

post-247365-071932700 1329111315_thumb.p

تحياتى العطرة والله الموفق ..

المرفقات
123.png

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#12

السلام عليكم

فقط من أجل توضيح بعض المصطلحات :

  • الـ buffer هي ذاكرة مؤقتة لتخزين البيانات أثناء انتقالها من طرف إلى آخر بحيث تختلف السرعة بين كلا الطرفين, باعتبار أن وصول البيانات إلى الطرف الثاني أسرع .. فإن دور الـ buffer يكمن في حفظ البيانات ريثما يكتمل وصولها إلى الطرف الأول لتكمل طريقها إلى الطرف الثاني و الذي غالبا ما يكون المعالج. على سبيل المثال : يتم استخدام الـ buffer عند كل عملية إدخال لأن الإنسان (الطرف الأول) بطبيعة حاله أبطأ من المعالج (الطرف الثاني).
    أيضا الـ buffer هو لقب يطلق على المتغيرات التي تستخدم لحفظ قيم مؤقتة و يمكن أن يكون مكان هذا المتغير بالـ Stack او Heap.
  • الـ Stack: هو مكان بالذاكره لابد من تحديد المساحه التى سيتم حجزها به وقت ترجمة البرنامج، هذا الجزء من الذاكره يحتوى على المتغيرات التى تم تعريفها داخل الكود أيا كان نوع هذه المتغيرات (ماعدا المتغيرات العامه) و أيضا المصفوفات التى تم تحديد حجم لها بشكل مباشر أو غير مباشر، أيضا تحتوى هذه الذاكره على شجرة إستدعاءات الدوال و قيم المعاملات. هذه الذاكره يتم تحريرها بمجرد العوده للداله التى قامت بالإستدعاء او بمجرد الإنتهاء من تنفيذ الداله الحاليه (تعتمد على طبيعة الإستدعاء cdecl او stdcall و توجد انواع اخرى).
  • الـ Heap: هو مكان بالذاكره مساحته يمكن تحديدها وقت ترجمة البرنامج أو وقت تشغيل البرنامج و لا يتم الحجز الفعلى للذاكره إلا بإستدعاء الدوال التى تقوم بتنفيذ عملية الحجز و حيث انك تقوم بعملية الحجز بشكل يدوى فإنك ملزم بتنفيذ عملية تحرير الذاكره بشكل يدوى أيضا و إن لم تقم بتحرير الذاكره قد يحدث Memory Leak مما قد يؤدى إلى انهاء برنامجك بشكل غير طبيعى او أمور أسوء.

عودا على بدء :

كما قلت لكم سابقا يمكننا كتابة دالة تتحقق من عدم حدوث الــ buffer Overflow عند إدخال قيمة للمتغير الحرفي. لذلك سنستخدم الدالة cin.getline للحصول على قيمة السطر بأكمله, بعدها سنقوم بالتحقق من قيمة السطر فإذا كان هذا الأخير يحتوى على أكثر من متغير حرفي فالنص مخالف :

bool Is_Char(const char* Char_string)
{
    int i;
        for(i = 0;*Char_string++;i++);
        if (i == 1) return true;
        else return false;
}

بالتوفيق.

تم تعديل هذه المشاركة بواسطة khaled_prg في 13 فبراير 2012 في 16:37

#13

استطيع ان افهم من مشاركة التالى:

khaled_prg كتب:

السلام عليكم

فقط من أجل توضيح بعض المصطلحات :

>>> ..........................

بالتوفيق.

أن الذكرة التى يمكن ان يستخدمها البرنامج يمكن تقسيمهم الى اربعة مناطق كمايلى:

  1. منطقة الكود: حيث يوجد بها كود البرنامج المترجم بالذاكرة.
  2. المنطقة العامة: حيث تخزن بها المتغيرات العامة
  3. منطقة heap : حيث تخزن بها الذاكرة المحجوزة ديناميكيا للمتغيرات
  4. منطقة stack: حيث تخزن بها الوسائط والمتغيرات المحلية

مشكور على المجهود الرائع وتقبل مرورى

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#14

جميل جدا هذا الحوار أستفدت معلومات كتيرة جدا وشكرا جدا لأخى محمد علاء الدين لمساعدتة وشكرا لأخى أحمد الشنقيطى وفعلا نصائح جوهرية ومهمة جدا وأسف على تأخر لطرح الكود بعد التغيير وفعلا المشكلة الى عاوز أحلها كما قال الاخ محمد أبو زايد

تتلخص فى البفر الذى يحتفظ بالقيم التى يدخلها المستخدم فيجب عند تكرار اللوب أن يتم محو كل محتوى اللوب حتى ينتظر البرنامج إدخال جديد من المستخدم

ويمكن أن نحل هذة المشكلة كما قال أخونا خالد من خلال (يمكننا كتابة دالة تتحقق من عدم حدوث الــ buffer Overflow) على ما أظن

أعذرونى لأنى مبتدى وكلامكو بدأ يبقى مش مفهوم قوى ليا وجزاكم الله خير

تم تعديل هذه المشاركة بواسطة ringawy في 14 فبراير 2012 في 13:46

#15

أخر تحديث للكود أتمنى أن لا يكون بة overflow على ما أظن معناها حمل زائد

وطبقت do while للتأكد من صحة المدخلات ولم أستطع التخلى عن goto فى جزئيتين المختصين بالتحقق من صحة عملية القسمة وباقى القسمة

وأيضا قمت بتعديل التحقق من مدخلات switch أوكلت عملية التحقق إلى حلة default أى إذا لم يكن الخيار واردا فأظهر التالى الموجود فى default بدون دوخة ووجع دماغ

ولى سؤال عن فكرة عمل دالة للتحقق من صحة الادخال يمكن إستدعائها بسهولة وفى أى جزء من البرنامج ؟؟

وهذا الكود بعد التحديث وأنتظر تعديلاتكم

/*
  Name: easy solver
  Copyright: rinGawy Team
  Author: mohamed elhabashe
  Date: 24/01/12 02:27
  Description: simpel calculator
*/
#include <limits>
#include <cstdlib>
#include <iostream>
float a,b;
int e,f,c;
using namespace std;
void Errorinput(void)
{
cout<<"-------------------------"<<endl<<"Error Enter your number again"<<endl<<"-------------------------"<<endl;
}

void Errormethod(void)
{
cout<<"-------------------------"<<endl<<"Error"<<a<<"/0 Wrong method cannot divide by zero please correct your method"<<endl<<"-------------------------"<<endl;
}

void Erroroperathion(void)
{
cout<<"-------------------------"<<endl<<"Error please Enter your operathion again"<<endl<<"-------------------------"<<endl;
}

void Erroronumber(void)
{
cout<<"-------------------------"<<endl<<"Error number input number between 1 or 2 or 3"<<endl<<"-------------------------"<<endl;
}

int main()
{
    bool test;
    char d;
    do{
         first:
    cout<<"hello this main menu please Enter your choice number"<<endl<<"1-Enter calculating program"<<endl<<"2-information about me"<<endl<<"3-no thanks get me out of here"<<endl<<"=>>";
    cin>>c; 
    switch(c)
    {
             case 1:{
                  do{
                  cout<<"welcome to my simple calculator"<<endl<<"Enter frist number =";
                  cin>>a;
    test=cin.fail();
    cin.clear();
    cin.ignore(std::numeric_limits<int>::max(),'\n');
    if(test==1)
    {
    system("cls");
    Errorinput();
    }
    }while(test);
                  do{
                  cout<<"Enter second number =";
                  cin>>b;
    test=cin.fail();
    cin.clear();
    cin.ignore(std::numeric_limits<int>::max(),'\n');
    if(test==1)
    {
    Errorinput();
    }
    }while(test);

                  again:
                  cout<<"Enter your arithmetic operathion like ( + , - , * , / ,% ) =";
                  cin>>d;
                      switch(d)
                      {
                      case '+':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"+"<<b<<"="<<a+b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '-':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"-"<<b<<"="<<a-b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '*':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"*"<<b<<"="<<a*b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '/':{
                           if(b==0)
                           {
                                  Errormethod();
                                  goto first;
                           }
                           else
                           cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"/"<<b<<"="<<a/b<<endl<<"------------------"<<system("cls")<<endl;break;
                           }
                      case '%':{
                           if(b==0)
                           {
                                  Errormethod();
                                  cin.clear();
                                  cin.ignore(std::numeric_limits<int>::max(),'\n');
                                  goto first;
                           }
                           else
                           e=(int)a;
                           f=(int)b;
                           cout<<"------------------"<<endl<<"Result of the calculation "<<e<<"%"<<f<<"="<<e%f<<endl<<"------------------"<<system("cls")<<endl;break;
                           }
                           default:{
                                    Erroroperathion();
                                    cin.clear();
                                    cin.ignore(std::numeric_limits<int>::max(),'\n');
                                    goto again;
                                    };           
                      }
                      };break;
               case 2:cout<<"---------------------------------"<<endl<<"my name: mohamed elhabashe"<<endl<<"my age: 25"<<endl<<"from: Egypt (country of fredoom)"<<endl<<"---------------------------------"<<endl;break;
               case 3:cout<<"bye bye see you later"<<endl;break;
               default:{
                        cin.clear();
                        cin.ignore(std::numeric_limits<int>::max(),'\n');
                        system("cls");
                        Erroronumber();
                        goto first;
                        };
               } 
}while(c!=3);
    system("PAUSE");
    return 0;
}

تم تعديل هذه المشاركة بواسطة ringawy في 13 فبراير 2012 في 22:39

#16

ايام ان كنت أقرأ من كتاب bjarne stroustrup كتبت هذا الكود او جمعته من الكتاب :)

/*
 * calculator.cpp
 *
 *  Created on: ١٤‏/٠٣‏/٢٠١١
 *  Author: Mohamed Fathei
 */
#include <iostream>
using std::istream;
using std::cout;
using std::cin;
using std::cerr;
using std::endl;

#include <string>
using std::string;

#include <sstream>
using std::istringstream;

#include <cctype>
using std::isalpha;
using std::isalnum;
using std::isspace;

#include <map>
using std::map;

map<string, double> table;

enum Token_value {
	NAME,
	NUMBER,
	END,
	PLUS = '+',
	MINUS = '-',
	MUL = '*',
	DIV = '/',
	PRINT = ';',
	ASSIGN = '=',
	LP = '(',
	RP = ')'
};

Token_value curr_tok = PRINT;

Token_value get_token();
double expr(bool);
double prim(bool);
double term(bool);

int num_of_errors;
double error(const string& s) {
	num_of_errors++;
	cerr << "ERROR : " << s << endl;
	return 1;
}

double number_value;
string string_value;

Token_value get_token() {

	char ch;
	do { // skip whitespace except '\n'
		if (!cin.get(ch))
			return curr_tok = END;
	} while (ch != '\n' && isspace(ch));

	switch (ch) {
	case ';':
	case '\n':
		return curr_tok = PRINT;
	case '*':
	case '/':
	case '+':
	case '-':
	case '(':
	case ')':
	case '=':
		return curr_tok = Token_value(ch);
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	case '.':
		cin.putback(ch);
		cin >> number_value;
		return curr_tok = NUMBER;
	default: // name
		if (isalpha(ch)) { // is letter
			string_value = ch;
			while (cin.get(ch) && isalnum(ch))
				string_value.push_back(ch);
			cin.putback(ch);
			return curr_tok = NAME;
		}
		error("bad token");
		return curr_tok = PRINT;

	}
}

// handle primaries
double prim(bool get) {
	if (get)
		get_token();
	switch (curr_tok) {
	case NUMBER: {
		double v = number_value;
		get_token();
		return v;
	}
	case NAME: {
		double& v = table[string_value];
		if (get_token() == ASSIGN)
			v = expr(true);
		return v;
	}
	case MINUS:
		return -prim(true);// unary minus
	case LP: {
		double v = expr(true);
		if (curr_tok != RP)
			return error(") expected");
		get_token(); // eat ')'
		return v;
	}
	default:
		return error("primary expected");

	}
}
// multiply and divide
double term(bool get) {

	double left = prim(get);
	for (;;)// forever
		switch (curr_tok) {
		case MUL:
			left *= prim(true);
			break;
		case DIV:
			if (double d = prim(true)) {
				left /= d;
				break;
			}
			return error("divide by 0");
		default:
			return left;
		}
}

// add and subtract
double expr(bool get) {

	double left = term(get);
	for (;;)// forever
		switch (curr_tok) {
		case PLUS:
			left += term(true);
			break;
		case MINUS:
			left -= term(true);
			break;
		default:
			return left;
		}

}

int main(int argc, char* argv[]) {

	istream* input;// pointer to input stream
	switch (argc) {
	case 1:
		input = &cin;
		break;
	case 2:
		input = new istringstream(argv[1]);
		break;
	default:
		error("too many arguments");
		return 1;
	}

	table["pi"] = 3.1415926535897932385;
	table["e"] = 2.7182818284590452354;

	while (cin) {
		get_token();
		if (curr_tok == END)
			break;
		if (curr_tok == PRINT)
			continue;
		cout << expr(false) << "\n";
	}

	if(input != &cin) delete input;
	return num_of_errors;
}

تجده فى Bjarne Stroustrup - The C++ Programming Language [special 3rd Edition]

تحياتى


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#17

شكرا لك أخى MOHAMED FATHEI سأقوم بتحميل الكتاب وقرأتة إن شاء الله ولكن يوجد مكتبات كتير مضمنة ولا أعرف إستخدامها سوف أبحث عنها أيضا

وجزاك الله خير

تم تعديل هذه المشاركة بواسطة ringawy في 14 فبراير 2012 في 13:46

#18

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

مرحبا : )

قمت باختبار الكود الذي كتبته و لاحظت ما يلي :

  • عندما يقوم المستخدم بتشغيل البرنامج و تظهر له الواجهة الرئيسية و يُدخل العدد 1.5 سيتم الدخول إلى الحاسبة, و هذا أكبر خطأ تم ارتكابه في الكود !!. لاحظ أنه تم الإنتقال إلى switch و بالضبظ إلى الــ case الأولى مع أن المُدخلات خاطئة !!, كما قال الأخ خالد فإن الحل هنا يكمن في كتابة دالة تتحقق من عدم حدوث الــ buffer Overflow عند إدخال قيمة المتغير. لذلك عليك باستخدام الدالة cin.getline للحصول على قيمة السطر بأكمله, بعدها ستقوم بــــالتحقق من قيمة السطر فإذا كان هذا الأخير يحقق شروط المتغير فالنص موافق و إلا فالنص مخالف.
  • بالمناسبة فإن هذه الثغرة تظهر في جميع مراحل برنامجك (كل إدخال) لذا عليك بأخذها في عين الاعتبار. أيضا لاحظت تكرارك لاستخدام cin.clear و cin.ignore !, من الأفضل أن تقوم بكتابة دالة خاصة بالإدخال مع مراعاة حدوث الــ buffer Overflow و قم باستدعائها عند كل عملية إدخال.
  • لا يتم مسح الشاشة عند إدخال 2 في الواجهة الرئيسية !!
  • عندما يُدخل المستخدم صفر للمتغير الثاني فعليك بــــمعالجة المشكلة آنيا و ذلك قبل الانتقال إلى إدخال رمز العملية.
  • طريقتك لكتابة الأسطر ليست منظمة فالأسطر الطويلة غير محببة لدى المبرمجين خصوصا عند تعقب أخطاء الكود, لذلك يُفضل تقسيم هذه الأسطر إلى أسطر قصيرة بحيث يستطيع القارئ قراءتها من نظرة واحدة.
  • الكود لا يحتوي على تعليقات و هذا خطأ بالغ لأنه مع تطوير الكود سيصبح مُكونا من آلاف الأسطر حينها ستكون عملية التعقب شبه مستحيلة لذا عليك استدراك كتابة التعليقات من الآن حتى لو كانت الدوال بسيطة فمجرد كتابة التعليقات سيساعدك مستقبلا على فهم و تطوير الكود.
  • ضع الدوال التي تستعملها في مكتبة و قم باستدعائها في أعلى البرنامج, سيساعدك هذا على تقسيم الكود و معالجة كل قسم على حده.
  • عليك بــــتغيير هذه الجزئية و ما شابهها :
    if(b==0)
    {  Errormethod();
       goto first;
    }


    استبدل goto ب do while.

  • إذا قمت باستخدام goto في برنامجك عدة مرات فــــسيكون الأمر سلبيا أكثر مما هو إيجابي لأن تداخل الـ goto فيما بينها سيجعلك غير قادر على تحديد بعض الأخطاء التي تنجم عن كثرة استخدام هذه التعليمة.

اقتباس
ايام ان كنت أقرأ من كتاب bjarne stroustrup كتبت هذا الكود او جمعته من الكتاب :)

كود جميل جدا, بارك الله فيك : )

أخي ringawy أظن أن فكرة الكود (الذي أرفقه محمد فتحي) ستكون المرحلة القادمة لمشروعك .. كتابة آلة حاسبة تدعم الأقواس و أولوية العمليات الحسابية :)

تحياتي.

تم تعديل هذه المشاركة بواسطة أحمد الشنقيطي في 14 فبراير 2012 في 19:51

#19

شكرا لك أخى أحمد على التعليق وسأعمل على الكود مع مراعاة جميع النقط التى ذكرتها

وأتمنى أن تكون خطوتى القادمة كما ذكرت مراعاة أولوية العمليات الحسابية وجزاكم الله جميعا كل خير

1
#21

لى سؤال بخصوص cin.getline و virable string

لأنى أول مرة أتعامل معهم

ما المشكلة فى الكود التالى لا يعمل ولا أعرف السبب

وهل يمكن إستعمال cin.getline مع المتغير من حرفى أو char

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string name[15];
    cin.getline(name,2,'\n');
    cout<<name;
    system("pause");
    return 0;
}

تم تعديل هذه المشاركة بواسطة ringawy في 16 فبراير 2012 في 06:04

#22

السلام عليكم

هل انت استخدمت الدالةهذة:

istream& getline (char* s, streamsize n, char delim );

أم الدالة هذة:

istream& getline ( istream& is, string& str, char delim );

لو استخدمت اﻻولى يبقى الكود كذلك:

#include <iostream>
#include <cstdlib> // for system()
using namespace std;

int main()
{

    char chname[150];
    cin.getline(chname, 2, '\n');
    cout << chname;
    system("pause");
    return 0;
}

// out put :
asdf
a
RUN SUCCESSFUL (total time: 4s)

لو استخدمت الدالة الثانية يبقى الكود كذلك:

#include <iostream>
#include <string>
using namespace std;

int main () {
  string strname;
  cout << "Please enter full name: ";
  getline (cin,strname, '\n');

  cout << "Thank you, " << strname << ".\n";
}

أذا أين تكمن المشكلة:

  • أن الدالة اﻻولى فى مكتبة السي++ القياسية أى ﻻ حاجة ﻻدراج ملف الهيدر string.h.
  • الدالة الثانية خاصة بالفئة string وتحتاج الى ادراج string.h
  • لاحظ: نركز قليلا بنوع وسيط الدالة يعنى هل هو من نوع char أم string وهذة امكانية توفرها معظم IDEs.
  • وماذا بعد: اذا كتبنا فهذا يعنى متغير
    string  strname;


  • أم اذا كتبنا التالى فأنة مصفوفة من نوع string
    string strname[2];


تحياتى العطرة والله ولى التوفيق

تم تعديل هذه المشاركة بواسطة محمد ابوزايد في 16 فبراير 2012 في 08:25

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#23

شكرا لك أخى محمد ابوزايد لقد وصلت المعلومة ولى سؤال أخر

هل يمكن إستعمال cin.getline مع char للدخول فى switch مثل الكود التالى

لأنة يظهر لى خطأ :switch quantity not an integer

والمتغير (d)معرف على أنة char

cout<<"Enter your arithmetic operathion like ( + , - , * , / ,% ) =";
                  cin.getline(d,2,'\n');
                      switch(d)
                      {
                      case '+':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"+"<<b<<"="<<a+b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '-':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"-"<<b<<"="<<a-b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '*':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"*"<<b<<"="<<a*b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '/':{

تم تعديل هذه المشاركة بواسطة ringawy في 17 فبراير 2012 في 21:34

#24
ringawy كتب:

شكرا لك أخى محمد ابوزايد لقد وصلت المعلومة ولى سؤال أخر

هل يمكن إستعمال cin.getline مع char للدخول فى switch مثل الكود التالى

لأنة يظهر لى خطأ :switch quantity not an integer

والمتغير (d)معرف على أنة char

cout<<"Enter your arithmetic operathion like ( + , - , * , / ,% ) =";
                  cin.getline(d,2,'\n');
                      switch(d)
                      {
                      case '+':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"+"<<b<<"="<<a+b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '-':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"-"<<b<<"="<<a-b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '*':cout<<"------------------"<<endl<<"Result of the calculation "<<a<<"*"<<b<<"="<<a*b<<endl<<"------------------"<<system("cls")<<endl;break;
                      case '/':{

ممكن ﻻ حظ الفرق واستنتج الخطأ:

/* 
 * File:   main.cpp
 * Author: Mohammed Abu Zayed
 * * Created on February 14, 2012, 3:17 PM
 */

#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

int main(int argc, char** argv)
{
    cout << "Enter your arithmetic operathion like ( + , - , * , / ,% ) =";
    char ch;
    cin.getline(&ch, 2, '\n');

    switch (ch)
    {
    case '+':cout << "++++++++++++++" << endl; //        
        break;
    case '-':cout << "------------------" << endl; //<< "R---
        break;
    case '*':cout << "***************" << endl; // << "Result o------l;
        break;
    case '/': cout << "//////////////////";
    default: cout << "I love u and like CPP tricks. " << endl;
    }
    return 0;
}

تقبل مرورى والله ولى التوفيق . . . . . .. . .......

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#25

أسف على كثرت أسئلتى ولكنى قبل أن أطرح أسئلتى فإنى قبل أن أطرح أسئلى أحاول وأفكر فيها كثيرا ولا أضع سؤال إلا بعد نفاد محاولاتى

وسؤالى هو

هل يمكن إستعمال cin.getline مع int للدخول فى switch مثل الكود التالى

لأنة يظهر لى خطأ :43 no matching function for call to `std::basic_istream<char, std::char_traits<char> >::getline(int*, int, char)'

والمتغير ©معرف على أنة int

cout<<"hello this main menu please Enter your choice number"<<endl<<"1-Enter calculating program"<<endl<<"2-information about me"<<endl<<"3-no thanks get me out of here"<<endl<<"=>>";
    cin.getline(&c,1,'\n');
    switch(c)
    {

تم تعديل هذه المشاركة بواسطة ringawy في 18 فبراير 2012 في 05:44

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

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

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

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

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