سؤال

هذا السؤال لديه بالفعل إجابة هنا:

أنا أتعلم لغة C++ وأكتب برامج صغيرة أثناء تقدمي.وفيما يلي أحد هذه البرامج:

// This program is intended to take any integer and convert to the
// corresponding signed char.

#include <iostream>

int main()
{
  signed char sch = 0;
  int n = 0;
  while(true){
    std::cin >> n;
    sch = n;
    std::cout << n << " --> " << sch << std::endl;
  }
}

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

#: ./int2ch
10
10 --> 

10000000000
10 -->

10 -->

10 -->

10 -->

يلفظ البرنامج "10 -->" حتى يتم قتله.(مع هذا التسلسل المحدد من المدخلات، تتغير سرعة مخرجات البرنامج بشكل غير منتظم.) لاحظت أيضًا أن إخراج القيم الكبيرة يتم تحديده من خلال الإدخال القانوني السابق بالإضافة إلى قيمة الإدخال غير القانوني الحالي.

ماذا يحدث هنا؟(لا يهمني إصلاح البرنامج، هذا سهل.أريد أن أفهم ذلك.)

هل كانت مفيدة؟

المحلول

في الأساس الخاص بك cin الدفق في حالة فشل وبالتالي يعود فورًا عند محاولة قراءته.أعد كتابة المثال الخاص بك مثل هذا:

#include <iostream>

int main()
{
  signed char sch = 0;
  int n = 0;
  while(std::cin >> n){
    sch = n;
    std::cout << n << " --> " << sch << std::endl;
  }
}

cin >> n سوف يعود إشارة إلى cin, ، والتي يمكنك اختبارها من أجل "الخير" في حالة شرطية.لذلك في الأساس "while(std::cin >> n)"يقول "بينما لا يزال بإمكاني القراءة من الإدخال القياسي بنجاح، قم بما يلي"

يحرر:السبب في إخراج آخر قيمة جيدة تم إدخالها بشكل متكرر هو أن هذه كانت آخر قيمة تم قراءتها بنجاح في n، ولن تغير القراءات الفاشلة قيمة n

يحرر:كما هو مذكور في التعليق، يمكنك مسح حالة الخطأ والمحاولة مرة أخرى، ومن المحتمل أن ينجح شيء كهذا وتجاهل الأرقام السيئة فقط:

#include <iostream>
#include <climits>

int main() {
    signed char sch = 0;
    int n = 0;
    while(true) {
        if(std::cin >> n) {
            sch = n;
            std::cout << n << " --> " << sch << std::endl;
        } else {
            std::cin.clear(); // clear error state
            std::cin.ignore(INT_MAX, '\n'); // ignore this line we couldn't read it
        }
    }
}

نصائح أخرى

نعم، لقد أشار إيفان تيران إلى معظم الأشياء بالفعل.شيء واحد أريد إضافته (بما أنني لا أستطيع التعليق على تعليقه بعد :)) هو أنه يجب عليك الاتصال بـ istream::clear قبل الدعوة إلى istream :: تجاهل.والسبب هو أن istream::ignore سيرفض أيضًا القيام بأي شيء إذا كان الدفق لا يزال في حالة الفشل.

نظرًا لأنك تستخدم جهازًا 32 بت، فإن 10000000000 يعد رقمًا كبيرًا جدًا بحيث لا يمكن تمثيله بواسطة int.كما أن تحويل int إلى char سيعطيك فقط من 0..255 أو -128..127 اعتمادًا على المترجم.

مشكلة واحدة هنا هي أن أ char يبلغ حجمه بايت واحد، وبالتالي يمكنه الاحتفاظ برقم يتراوح بين -127 و128 فقط.ان int من ناحية أخرى، يبلغ عادةً 4 بايت، ويمكن أن يأخذ قيمًا أكبر بكثير.المشكلة الثانية هي أنك تقوم بإدخال قيمة كبيرة جدًا حتى بالنسبة لـ int.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top