عندما تشغل الشفرة أعلاه، ستلاحظ أنه تُطلب منك إدخال العدد مرتين، وذلك بسبب كيفية عمل الجملة while (!(cin>>x))
.
دعوني أشرح لك كيفية عمل هذه الجملة في الشفرة:
- تقوم
cin>>x
بمحاولة قراءة عدد من المدخل القياسي (stdin) وتخزينه في المتغيرx
. - إذا كانت العملية ناجحة، فإن
cin>>x
ستعيد قيمة صحيحة (true)، وبالتالي فإن!
ستحول هذه القيمة إلى قيمة خاطئة (false). - لذا، الجملة
while (!(cin>>x))
ستكون معادة إلىwhile (false)
، وبالتالي لن يتم دخول الحلقة.
لكن، إذا فشلت cin>>x
في قراءة عدد صحيح، ستعيد قيمة خاطئة (false)، وبالتالي سيتم تنفيذ ما بعد while (!(cin>>x))
. وفي هذه الحالة، سيتم عرض رسالة “Invalid value !” ومن ثم تنفيذ system("pause")
لتوقيف البرنامج وانتظار إدخال مفتاح من قبل المستخدم.
المشكلة هنا هي أنه بعد عرض الرسالة وتوقف البرنامج، عندما تدخل قيمة صحيحة جديدة، فإن cin>>x
ستحاول قراءتها لكن لن يتم تخزينها في x
بل ستستمر في اعتبار المدخل (stdin) مشكلاً مع cin>>number
الذي يأتي بعدها، مما يؤدي إلى طلب إدخال العدد مرة أخرى.
لحل هذه المشكلة، يمكنك استخدام دالة clear()
لمسح حالة الخطأ من cin
بعد عرض الرسالة، ودالة ignore()
لتجاهل أي بقايا في المدخل (stdin) قبل قراءة العدد الجديد. وهناك طرق أخرى لتحسين البرنامج أيضًا، مثل استخدام محاولة واستدراج المستخدم لإدخال قيمة صحيحة.
المزيد من المعلومات
بعد توضيح المشكلة في الشفرة وكيفية عمل جملة while (!(cin>>x))
، يمكننا الآن التركيز على كيفية حل هذه المشكلة بشكل فعال.
أحد الطرق الشائعة لحل هذه المشكلة هي استخدام دالة clear()
لمسح حالة الخطأ من cin
بعد عرض الرسالة، واستخدام دالة ignore()
لتجاهل أي بقايا في المدخل (stdin) قبل قراءة العدد الجديد. هذا يضمن أننا نستأنف قراءة العدد الجديد من البداية، دون أي ارتباك.
لذا، يمكننا تعديل الشفرة بشكل يحقق هذا الهدف كما يلي:
cpp#include
using namespace std;
int main() {
int x;
int number;
cout << "Please enter an integer: ";
cin >> number;
// Check if the input is valid
while (!(cin >> x)) {
cout << "Invalid value! Please enter an integer: ";
// Clear the error state
cin.clear();
// Ignore any remaining characters in the input buffer
cin.ignore(numeric_limits::max(), '\n');
}
cout << "Your number is: " << number << endl;
return 0;
}
في هذا التعديل، بمجرد أن يفشل cin>>x
في قراءة العدد المطلوب، سيتم عرض رسالة الخطأ ومن ثم سيتم مسح حالة الخطأ باستخدام clear()
، وستتم محاولة تجاهل أي بقايا في المدخل (stdin) باستخدام ignore()
لضمان بدء القراءة من البداية مرة أخرى.
هذه التعديلات تجعل البرنامج أكثر استدامة ويسهل فهمه واستخدامه للمستخدم، مما يساهم في تحسين تجربة المستخدم وجعل البرنامج أكثر مرونة في التعامل مع الإدخالات غير الصالحة.