اذهب إلى المحتوى

السؤال

نشر

أحاول أن أقوم بعمل برنامج بسيط، يطلب من المستخدم الاسم الكامل ولكن تظهر مشكلة وهي أن التابع cin يقوم بتقسيم المدخلات بالمسافات ويأخذ أول كلمة فقط:

std::cout << "Enter your full name: ";
std::string name{};
std::cin >> name; // هنا يتم تخزين أول كلمة فقط

std::cout << "Enter your age: ";
std::string age{};
std::cin >> age;	// هنا يتم تخزين ثاني كلمة 

std::cout << "Your name is " << name << " and your age is " << age << '\n';

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

Enter your full name: Mohssen Ahmed
Enter your age: Your name is Mohssen and your age is Ahmed

لاحظ كيف تم تخزين الكلمة Ahmed في المتغير age ولم ينتظر إلى أن يقوم المستخدم بإدخال القيمة الثانية.

ما سبب هذه المشكلة؟ وكيف أقوم بحلها؟

Recommended Posts

  • 1
نشر

سبب المشكلة هو أن التابع std::cin يقةم بتقسيم المدخلات بالمسافات ويقوم بإستخدام أول جزء فقط (الكلمة "Mohssen") ويخزن الجزء الباقي، وعندما تستخدم std::cin مرة ثانية فإنه يجد الجزء الثاني (الكلمة "Ahmed") موجودة بالفعل، فيقوم بإستخدامها مباشرة دون إنتظار المستخدم لإدخال كلمات أخرى.

لحل هذه المشكلة يمكنك أن تقوم بإدخال القيمة من خلال التابع std::getline حيث يقوم هذا التابع بإستقبال سطر كامل (إي إلى أن يصل إلى n\) ويمكنك تستخدمه كالتالي:

std::cout << "Enter your full name: ";
std::string name{};
std::getline(std::cin >> std::ws, name); // قراءة سطر كامل إلى المتغير name

std::cout << "Enter your age: ";
std::string age{};
std::getline(std::cin >> std::ws, age); // قراءة سطر كامل إلى المتغير age

std::cout << "Your name is " << name << " and your age is " << age << '\n';

وستكون المدخلات كالتالي:

Enter your full name: Mohssen Ahmed
Enter your age: 23
Your name is Mohssen Ahmed and your age is 23

ما هو std::ws؟

الكائن std::ws هو معالج الدخل input manipulator، أي أنه يقوم بتعديل المدخلات قبل أن يتم تخزينها، والهدف منه هو أن يجعل التابع std::getline يتجاهل أي محارف فارغة في بداية النص، فعلى سبيل المثال إذا لم نقم بإستخدامه في الكود التالي:

std::cout << "choose 1 or 2: ";
int choice{};
std::cin >> choice;

std::cout << "Enter your name: ";
std::string name{};
std::getline(std::cin, name); // لاحظ أننا لم نستعمل std::ws هنا

std::cout << "Hello, " << name << ", you picked " << choice << '\n';

ونتيجة الكود السابق سوف تكون:
 

Choose 1 or 2: 2
Enter your name: Hello, , you picked 2

عندما تقوم بإدخال رقم 2 ثم تضغط على Enter (أي أنك تقوم بإدخال n\ إلى نهاية النص)، يقوم التابع std::getline بأخذ القيمة الرقمية فقط وهي 2 ويترك n\ مخزنة، وعندما تقوم بإستخدام التابع std::getline مرة أخرى فإنه يجد القيمة n\ موجودة بالفعل ويقوم بتخزينها في المتغير name، لهذا يجب أن تستخدم معالج الدخل std::ws لكي يتم تجاهل أي محارف فارغة (المسافة n\ أو t\ .. إلخ) من بداية المدخل، فيتم تجاهل وجود n\ وينتظر حتى يقوم المستخدم بإدخال اسمه.

يمكنك أن تقرأ أكثر حول معالج الدخل من خلال هذه المقالة:

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...