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

سؤال حول التحقق من صحة الإدخال.

بدأه khaled_prg في 30 يونيو 2010 · 19 رد · 1,146 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

يمكننا استخدام التعبير cin.fail للتحقق من صحة الإدخال:

#include<iostream>
using namespace std;
int main()
{
    int n;
    cout<<"n=";
    cin>>n;
    if(cin.fail())
    cout<<"erreur!\a"<<endl;
    else
    cout<<n<<endl;
    system("pause");
    return 0;
}

حيث يكون هذا التعبير خاطئا:

cin.fail()=false

إذا تمت عملية الإدخال بشكل صحيح.. و يكون صحيحا:

cin.fail()=true

إذا لم تتم عملية الإدخال بالشكل المطلوب.

و لكن الغريب في الأمر ما يحدث لي عند استخدامه في الدوارة while

#include<iostream>
using namespace std;
int main()
{
    int n;
    do
    {
    cout<<"Enter an integer number:";
    cin>>n;
    system("cls");
    }while(cin.fail());
    return 0;
}

هناك خطأ منطقي في البرنامج ...! و لكنني لا أعلم سببه :blush:

أرجوا منكم التوضيح.

قال لي أحد الأعضاء:

اقتباس
لخطا انك استخدم الشرط while شرط مثبت فلابد من نفيه حتى يتم تحقيق الشرط

لان الشرط لم يتحقق هكذا

انت تقول للبرنامج افعل هذا الكود اكثر من مره عندما يكون الادخال خاطئ

لذا عليك بنفى الشرط داخل while

هذا ما فهمته من سوالك وان كان خطا ف الفهم ارجوا التوضيح

#include<iostream> 
using namespace std; 
int main() 
{ 
    int n; 
    do{
                cout<<"Enter an integer number:"; 
                cin>>n;
                system("cls"); 
        }while(!cin.fail()); 
    return 0; 
}

لكن الكود ما زال لا يؤدي المطلوب ....!

#2

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

ممكن تقولى ايه هو المطلوب لان دا الللى انا فهمته ووبناء عليه عملت التصحيح دا

ممكن تقول المطلوب ؟؟؟؟

ملحوظه

عند استخدامك للـ do...while

فانك تقوم بتنفيذ الكود مره واحده بدون فحص المدخلات

فلكى يكون الفحص صحيح استخدم while بدلا من do...while

هكذا

#include<iostream> 
using namespace std; 
int main() 
{ 
	int n; 
	while(!cin.fail()){
		cout<<"Enter an integer number:"; 
		cin>>n;
		system("cls"); 
	}
	return 0; 
}

ووممكن تلغى عمل السطر هذا

system("cls");

بصراحه لا اعلم ما فائدته غير انه يمسح لى الشاشه كلها لماذا ؟؟

جرب الكود تبعى وجربه بدون هذا السطر

وان لم تظهر لك ما تريد افهمنا ماذا تنتظر من البرنامج ان يفعل ؟؟

سلام عليكم

Software Developer
Mahmoudkelany.com


 

#3
اقتباس
ممكن تقولى ايه هو المطلوب لان دا الللى انا فهمته ووبناء عليه عملت التصحيح دا

ممكن تقول المطلوب ؟؟؟؟

المطلوب هو:

يقوم المستخدم بإدخال شيء معين .. فإذا كان عدد صحيح فسيتم تخزينه في المتغير n و إلا فسيقوم البرنامج بطلب إدخال جديد و هكذا حتى يُدخل المستخدم عدد صحيح :) , و بالمناسبة فإن الكود يفعل العكس تماما.

اقتباس
ووممكن تلغى عمل السطر هذا

system("cls");

بصراحه لا اعلم ما فائدته غير انه يمسح لى الشاشه كلها لماذا ؟؟

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

#4

السلام عليكم

المشكلة ليست في cin.fail، المشكلة هي أنه عندما يتم إسناد قيمة double إلى int يتم تحويلها إلى int، وهذا ينطبق على cin الذي يستقبل عدداً غير صحيح، لنقل 5.5 على سبيل المثال، ويطلب منه وضعه في متغير int، فسيقوم بتحويله إلى النوع int ليصبح 5، ولن يتحقق حينها cin.fail، وحتى بشكل عام، عندما تسند قيمة double إلى int يتم تحويلها:

int a= 5.5

ستكون قيمة a مساوية للـ5.

إذاً سيكون الحل بأن نمنع التحويل Casting، وهو ما لا أعلم طريقته، أو حتى إن كان ممكناً أم لا، لكن يمكنك مؤقتاً الاستفادة من هذه الطريقة:

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

bool IsInt(double n);

int main() 
{ 
    int n; 
	double temp;
    do
	{
		cout<<"Enter an integer number:"; 
        cin>> temp;
        system("cls");
    }while(!IsInt(temp));
	n= temp;
    return 0; 
}

bool IsInt(double n)
{
	return n == floor(n);
}

علماً أني أظنك لن تحتاج لهذا، بما أن القيمة تتحول لوحدها إلى int، فلماذا وجع الرأس؟

بالتوفيق

تم تعديل هذه المشاركة بواسطة Abboodd في 30 يونيو 2010 في 20:50

هذه الجملة خاطئة  :wacko: 


#5
اقتباس
السلام عليكم

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

اقتباس
المشكلة ليست في cin.fail، المشكلة هي أنه عندما يتم إسناد قيمة double إلى int يتم تحويلها إلى

أنا لم أقل أن المستخدم سيُدخل double ...! يُمكنه أن يُدخل رمزا أو جملة أو أي شيء آخر .. و هنا يأتي دور التحقق من صحة الإدخال :)

#6

مممم، المسألة معقدة، حاولت إفراغ الـbuffer الخاص بـcin، لكني لم أستفد...

البحث جارٍ....

هذه الجملة خاطئة  :wacko: 


#7

جرب التالي أخي الكريم:

#include<iostream>
using namespace std;
int main()
{
	int n;
	bool bad_input;
	do
	{
		bad_input= false;

		cout<<"Enter an integer number:";
		cin>> n;
		if (cin.fail())
		{
			bad_input= true;
			cin.clear();
			cin.ignore();
			system("cls");
		}
    }while(bad_input);
	cout<< n;
	return 0;
}

تم تعديل هذه المشاركة بواسطة Abboodd في 2 يوليو 2010 في 00:46

1

هذه الجملة خاطئة  :wacko: 


#8
اقتباس

جرب التالي أخي الكريم:

#include<iostream>
using namespace std;
int main()
{
        int n;
        bool bad_input;
        do
        {
                bad_input= false;

                cout<<"Enter an integer number:";
                cin>> n;
                if (cin.fail())
                {
                        bad_input= true;
                        cin.clear();
                        cin.ignore();
                        system("cls");
                }
    }while(bad_input);
        cout<< n;
        return 0;
}

الآن أصبح الكود يؤدي الطلوب و لكنه يحتاج إلى بعض التوضيح :)

ملاحظة:ألا يمكننا الإكتفاء بالتعبير cin.fail دون إضافات !؟

#9

المشكلة ان الـ buffer لا يزال به المدخلات القديمة

لذا لزم التخلص منها :wink:

هذا حسب خبرتي المتواضعة في استعمل الـــ cin.fail

#10

نحتاج إلى cin.clear لإزالة حالة الـfail، ونحتاج إلى cin.igonre لإزالة الحرف الذي سبب الـfail من الـbuffer.

وضعتها في شرط داخل الحلقة، لكي لا نقوم بعمليات clear وigonre إلا في حال وجود خطأ، حيث أنني لو وضعت شرط حلقة while ليكون cin.fail، فهذا يعني أنني سأضطر إلى تنفيذ clear وignore حتى لو كانت النتائج صحيحة، مما سيسبب أخطاء في البرنامج.

بالتوفيق

1

هذه الجملة خاطئة  :wacko: 


#11

+1 على الشرح المميز :)

اقتباس
نحتاج إلى cin.clear لإزالة حالة الـfail، ونحتاج إلى cin.igonre لإزالة الحرف الذي سبب الـfail من الـbuffer.

وضعتها في شرط داخل الحلقة، لكي لا نقوم بعمليات clear وigonre إلا في حال وجود خطأ، حيث أنني لو وضعت شرط حلقة while ليكون cin.fail، فهذا يعني أنني سأضطر إلى تنفيذ clear وignore حتى لو كانت النتائج صحيحة، مما سيسبب أخطاء في البرنامج.

ماذا تقصد بالـ buffer ؟

يا ريت تضع شرح مبسط حول استخدام و فائدة كل من cin.clear و cin.igonre.

و أعتذر عن كثرة الأسئلة :blush:

#13
اقتباس

ماذا تقصد بالـ buffer ؟

http://en.wikipedia.org/wiki/Data_buffer

اقتباس

cin.clear

تقوم هذه الدالة بتنظيف قيم الـError، أي أنها تعيد قيم fail وأخواتها إلى false.

اقتباس

cin.ignore

http://www.cplusplus.com/reference/iostream/istream/ignore/

http://www.cplusplus.com/forum/beginner/9148/

اقرأ أولى الوصلتين للمعلومات العامة عن igonre، والثانية لمعرفة فائدتها.

يمكنك القول بكل بساطة أن ignore تقوم بتجاهل عدد من الحروف في الـbuffer، حسن، ما رأيك بمثال:

string a;
cin>> a;

وكان إدخال المستخدم على سبيل المثال: "Hello World!"، فإن cin ستقوم باستخلاص Hello فقط وتترك الباقي، لأن المعامل (<<) لا يأخذ إلا كلمة واحدة.

إذاً، ما الذي حصل لباقي الجملة؟

سيبقى في الـbuffer، وحين يتم استدعاء دالة أخرى من cin، ستتلقاه مباشرة، فلو كتبت بعدها:

string b;
cin>> b;

ستجد أن b سيأخذ القيمة " World!" مباشرة، وينهي إدخاله.

جرب هذا المثال لترى بنفسك:

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

int main()
{
	string a;
	cin>> a;
	cout<< a<< endl;

	string b;
	cin>> b;
	cout<< b<< endl;
	return 0;
}

لذلك تستعمل igonre، لإزالة هذه الحروف الباقية في الـbuffer، كالتالي مثلاً:

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

int main()
{
	string a;
	cin>> a;
	cout<< a<< endl;
	cin.ignore(255, '\n');
	string b;
	cin>> b;
	cout<< b<< endl;
	return 0;
}

وضعت الوسيط الأول 255 لأتأكد من إزالة كل الحروف السابقة، ضعه أي عدد تريده، لكن تأكد من أن يكون أكبر من عدد الحروف الباقية في الـbuffer.

بالتوفيق

تم تعديل هذه المشاركة بواسطة Abboodd في 3 يوليو 2010 في 11:01

2

هذه الجملة خاطئة  :wacko: 


#14
اقتباس

للأسف الشديد :blush: نحن ندرس باللغة الفرنسية و لا أعرف الإنجليزية فياريت تترجم المحتوى إلى اللغة العربية أو الفرنسية أذا أمكن.

اقتباس
تقوم هذه الدالة بتنظيف قيم الـError، أي أنها تعيد قيم fail وأخواتها إلى false.

ما ذا تقصد بـ fail , كل ما أعلمه هو cin.fail و ليس fail لوحدها !

ماذا تعني بأخواتها ...!؟

اقتباس

أرجوا منك ترجمة المحتوى إلى العربية أو الفرنسية.

#15

بالنسبة لـbuffer:

من الموقع ذاته:

http://fr.wikipedia.org/wiki/M%C3%A9moire_tampon

بالنسبة لـfail فقد قصدت بها cin.fail، وأخواتها تعبير من عندي، يعني أقصد الـError Flags الخاصة بـcin كـcin.fail وcin.bad....

بالنسبة لـignore، فتقوم بحذف عدد محدد من الحروف من الـbuffer، وسيطها الأول يحدد عدد الحروف المراد حذفه، ووسيطها الثاني يحدد الحرف الذي إذا وجدته ignore تقوم بإيقاف الحذف.

راجع ما أضفته بعد ذلك في ردي السابق لتتوسع في المعلومة

وحاول تعلم اللغة الإنكليزية، فهي ضرورية في البرمجة بشكل كبير.

أي سؤال آخر أو شيء غير مفهوم بعد أنا جاهز إن شاء الله.

بالتوفيق.

1

هذه الجملة خاطئة  :wacko: 


#16
اقتباس
بالنسبة لـfail فقد قصدت بها cin.fail، وأخواتها تعبير من عندي، يعني أقصد الـError Flags الخاصة بـcin كـcin.fail وcin.bad....

ما هي cin.bad !؟

اقتباس
وحاول تعلم اللغة الإنكليزية، فهي ضرورية في البرمجة بشكل كبير.

عندك حق :blush:

اقتباس
أي سؤال آخر أو شيء غير مفهوم بعد أنا جاهز إن شاء الله.

أكرمك الكريم .. يعجز لساني عن شكرك :wub:

#17

تعيد cin.bad القيمة true عندما يحدث خطأ يخل بنظام الـstream.

لست متأكداً تماماً من عملها أو الفرق بينها وبين cin.fail، لكن أظنها تذهب إلى فشل عملية الإدخال أو الإخراج ككل، وليس مشكلة في أنواع البيانات أو كذا.

والله أعلم

بالتوفيق

هذه الجملة خاطئة  :wacko: 


#18

و هذه طريقة أخرى:

#include<iostream>
using namespace std;
int main()
{
    int n;
    do
    {
    cout<<"Enter an integer number:";
	cin.clear();
	cin.sync();
    cin>>n;
    system("cls");
    }while(cin.fail());
    return 0;
}

دمتم في رعاية الله و حفظه.

1
#19

تفضل أخي الكريم

هذه طريقة أخرى :

#include <iostream>
#include <limits>

using namespace std;

int main()
{
	int n;
	bool cond;

	do
	{
		cout << "Enter an integer number : ";

		cin >> n;

		cond = cin.fail();

		cin.clear();

		cin.ignore(std::numeric_limits<int>::max(),'\n');

	}while(cond);

	return 0;
}

تم تعديل هذه المشاركة بواسطة namespace في 8 يوليو 2010 في 18:13

البرمجة = الرياضيات

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