سؤال

لذلك أنا حاليًا أتعلم لغة C++ وقررت إنشاء برنامج يختبر مهاراتي التي تعلمتها حتى الآن.الآن في الكود الخاص بي، أريد التحقق مما إذا كانت القيمة التي يدخلها المستخدم مزدوجة، وإذا لم تكن مزدوجة فسأضع حلقة if وأطلب منهم إعادة إدخالها.المشكلة التي أواجهها هي كيف يمكنني التحقق من نوع المتغير الذي يدخله المستخدم، على سبيل المثال، إذا أدخل المستخدم حرفًا أو سلسلة، فيمكنني إخراج رسالة خطأ.هنا هو الكود الخاص بي:

//cubes a user entered number
#include <iostream>
using namespace std;

double cube(double n); //function prototype

int main()
{
    cout << "Enter the number you want to cube: "; //ask user to input number
    double user;
    cin >> user;  //user entering the number

    cout << "The cube of " << user << " is " << cube(user) << "." << endl; //displaying the cubed number

    return 0;
}

double cube (double n) //function that cubes the number
{
    return n*n*n; // cubing the number and returning it
}

يحرر:أود أن أقول إنني بدأت للتو وليس لدي أدنى فكرة عن الكود الخاص بك، ولكنني سأتحقق من الرابط الخاص بك.بالمناسبة، لم أتعلم كيفية العمل مع القوالب بعد، فأنا أتعلم كيفية التعامل مع البيانات، فقط الفصل الثالث في الإصدار الخامس من C++ Primer Plus.

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

المحلول

ولا توجد وسيلة مناسبة للتحقق مما إذا سلسلة <م> حقا يحتوي على ضعف داخل المكتبة القياسية. ربما كنت ترغب في استخدام زيادة . مستوحاة الحل التالية وصفة 3.3 في C ++ كتاب الطبخ :

#include <iostream>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;

double cube(double n);

int main()
{
    while(true)
    {
        cout << "Enter the number you want to cube: ";
        string user;
        cin >> user;

        try
        {
            // The following instruction tries to parse a double from the 'user' string.
            // If the parsing fails, it raises an exception of type bad_lexical_cast.
            // If an exception is raised within a try{ } block, the execution proceeds
            // with one of the following catch() blocks
            double d = lexical_cast <double> (user);   

            cout << "The cube of " << d << " is " << cube(d) << "." << endl;
            break;
        }
        catch(bad_lexical_cast &e)
        {
            // This code is executed if the lexical_cast raised an exception; We
            // put an error message and continue with the loop
            cout << "The inserted string was not a valid double!" << endl;
        }
    }
    return 0;
}

double cube (double n)
{
    return n*n*n;
}

نصائح أخرى

طريقة آمنة لـ C++

يمكنك تحديد وظيفة لهذا باستخدام std::istringstream:

#include <sstream>  

bool is_double(std::string const& str) {
    std::istringstream ss(str);

    // always keep the scope of variables as close as possible. we see
    // 'd' only within the following block.
    {
        double d;
        ss >> d;
    }

    /* eat up trailing whitespace if there was a double read, and ensure
     * there is no character left. the eof bit is set in the case that
     * `std::ws` tried to read beyond the stream. */
    return (ss && (ss >> std::ws).eof());
}

لمساعدتك في معرفة ما تفعله (تم تبسيط بعض النقاط):

  • إنشاء سلسلة إدخال تمت تهيئتها باستخدام السلسلة المقدمة
  • قراءة قيمة مزدوجة منه باستخدام operator>>.وهذا يعني تخطي المسافات البيضاء ومحاولة قراءة مزدوجة.
  • إذا لم يكن من الممكن قراءة أي مزدوج، كما في abc الدفق يحدد يفشل-قليل.لاحظ أن الحالات مثل 3abc سوف تنجح وسوف لا تعيين بت الفشل.
  • إذا تم تعيين بت الفشل، ss يقيم إلى قيمة صفر، وهو ما يعني خطأ شنيع.
  • إذا تمت قراءة مزدوج، فإننا نتخطى المسافة البيضاء الزائدة.إذا كنا بعد ذلك في نهاية الدفق (لاحظ ذلك eof() سيعود حقيقي إذا حاولنا أن نقرأ بعد النهاية. std::ws يفعل ذلك بالضبط)، eof سوف يعود صحيحا.لاحظ أن هذا الفحص يتأكد من ذلك 3abc لن يمر الشيك لدينا.
  • إذا كان في الحالتين يمين ويسار && تقييم ل حقيقي, ، نعود صحيحًا للمتصل، مع الإشارة إلى أن السلسلة المحددة مزدوجة.

مماثلة، يمكنك التحقق من ذلك int وأنواع أخرى.إذا كنت تعرف كيفية العمل مع القوالب، فأنت تعرف كيفية تعميم ذلك على الأنواع الأخرى أيضًا.بالمناسبة، هذا هو بالضبط ما boost::lexical_cast يوفر لك.تحقق من ذلك: http://www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htm.

ج الطريق الأول

تتمتع هذه الطريقة بمزايا (السرعة) ولكن لها أيضًا عيوبًا كبيرة (لا يمكن تعميمها باستخدام قالب، وتحتاج إلى العمل باستخدام مؤشرات أولية):

#include <cstdlib>
#include <cctype>  

bool is_double(std::string const& s) {
    char * endptr;
    std::strtod(s.c_str(), &endptr);
    if(endptr != s.c_str()) // skip trailing whitespace
        while(std::isspace(*endptr)) endptr++;
    return (endptr != s.c_str() && *endptr == '\0');
}

strtod سيتم تعيين endptr إلى الحرف الأخير الذي تمت معالجته.وهو في حالتنا حرف الإنهاء الفارغ.إذا لم يتم إجراء أي تحويل، فسيتم تعيين endptr على قيمة السلسلة المعطاة لها strtod.

ج الطريق الثاني

قد يعتقد المرء ذلك std::sscanf عمل الحيلة.لكن من السهل الإشراف على شيء ما.إليك الطريقة الصحيحة للقيام بذلك:

#include <cstdio>

bool is_double(std::string const& s) {
    int n;
    double d;
    return (std::sscanf(s.c_str(), "%lf %n", &d, &n) >= 1 && 
            n == static_cast<int>(s.size()));
}

std::sscanf سوف يعود العناصر المحولة.على الرغم من أن المعيار يحدد ذلك %n لم يتم تضمينه في هذا العدد، عدة مصادر تناقض بعضها البعض.إنها الأفضل للمقارنة >= للحصول على ذلك بشكل صحيح (راجع صفحة sscanf). n سيتم ضبطه على مقدار الأحرف المعالجة.تتم مقارنتها بحجم السلسلة.تمثل المسافة بين محددي التنسيق مسافة بيضاء زائدة اختيارية.

خاتمة

إذا كنت مبتدئا، اقرأ std::stringstream وقم بذلك بطريقة C++.من الأفضل عدم العبث بالمؤشرات حتى تشعر بالرضا عن المفهوم العام لـ C++.

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

//cubes a user entered number
#include <iostream>
#include <cstdio>
using namespace std;

double cube(double n); //function prototype

int main()
{
        cout << "Enter the number you want to cube: "; //ask user to input number
        string user;
        cin >> user;  //user entering the number

        // Convert the number to a double.
        double value;
        if(sscanf(user.c_str(), "%lf", &value) != 1)
        {
                cout << "Bad!  " << user << " isn't a number!" << endl;
                return 1;
        }

        cout << "The cube of " << user << " is " << cube(user) << "." << endl; //displaying the cubed number

        return 0;
}

double cube (double n) //function that cubes the number
{
        return n*n*n; // cubing the number and returning it
}

وسائل أخرى نشرت في إجابات أخرى لها مزاياها وعيوبها. هذا واحد لديه مشاكل مع شخصيات زائدة وليس "C ++" - ذ

وأود أن أقول إنني بدأت للتو وليس لديهم أدنى فكرة عن من التعليمات البرمجية الخاصة بك، ولكنني لن تحقق من وصلتك. بالمناسبة، أنا لم يتعلموا كيفية العمل مع القوالب حتى الآن، وأنا أتعلم عن التعامل مع البيانات، الفصل 3 فقط في بلدي C ++ التمهيدي زائد 5th الطبعة.

ويمكن أن تقع مرة أخرى على C واستخدام strtod

والبرنامج الذي يقرأ في سلسلة ثم يمررها إلى وظيفة الذي يحاول تحويل السلسلة إلى الضعف.

bool is_double(const char* strIn, double& dblOut) {
    char* lastConvert = NULL;
    double d = strtod(strIn, &lastConvert);
    if(lastConvert == strIn){
        return false;
    } else {
       dblOut = d;
       return true;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top