سؤال

ما هي الطريقة الأكثر أمانا وأفضل طريقة لاسترداد طويلة غير موقعة من سلسلة في C ++؟

أنا أعرف عددا من الأساليب المحتملة.

أولا، تحويل موقعة منذ فترة طويلة من ATOL.

char *myStr; // Initalized to some value somehow.
unsigned long n = ((unsigned)atol(myStr));

المشكلة الواضحة مع هذا هي، ما يحدث عندما تكون القيمة المخزنة في MySrS أكبر من فترة طويلة يمكن أن تحتوي على؟ ماذا استرداد الأوتول؟

الاحتمال التالي هو استخدام sttoul.

char *myStr; // Initalized to some value somehow.
unsigned long n = strtoul(myStr, 0, 10);

ومع ذلك، هذا أكثر قليلا معقد لاحتياجاتي. أريد وظيفة بسيطة، سلسلة داخل، قاعدة طويلة غير موقعة 10 خارج. أيضا، معالجة الأخطاء يترك الكثير مما هو مرغوب فيه.

الاحتمال الأخير الذي وجدته هو استخدام SSCanf.

char *myStr; // Initalized to some value somehow.
unsigned long n = 0;
if(sscanf(myStr, "%lu", n) != 1) {
    //do some error handling
}

مرة أخرى، يتعامل مع الأخطاء يترك الكثير مما هو مرغوب فيه، وأكثر تعقيدا قليلا مما أود.

الخيار الواضح المتبقي هو اكتب بلدي إما مجمع حول أحد الاحتمالات السابقة أو بعض الشيء الذي دورات من خلال السلسلة وتحويل كل رقم يدويا حتى تصل إلى ULONG_MAX.

سؤالي هو، ما هي الخيارات الأخرى التي فشلت فيها Google-Fu في العثور عليها؟ أي شيء في مكتبة C ++ STD التي ستحويل سلسلة نظيفة إلى استثناءات غير موقعة طويلة ورمي على الفشل؟

اعتذاري إذا كانت هذه دوب، لكنني لم أستطع العثور على أي أسئلة مطابقة تماما.

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

المحلول

طريقة واحدة للقيام بذلك:

stringstream(str) >> ulongVariable;

نصائح أخرى

يمكنك استخدام Strtoul بدون مشكلة. تقوم الوظيفة بإرجاع فترة طويلة غير موقعة. إذا كان لا يمكن إجراء التحويل الدالة إرجاعها 0. إذا كانت القيمة الطويلة الصحيحة خارج نطاق إرجاع الوظيفة ULONG_MAX ويتم تعيين المتغير Global Errno إلى Erange.

template <class T>
T strToNum(const std::string &inputString,
           std::ios_base &(*f)(std::ios_base&) = std::dec)
{
    T t;
    std::istringstream stringStream(inputString);

    if ((stringStream >> f >> t).fail())
    {
        throw runtime_error("Invalid conversion");
    }
    return t;
}


// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue             = strToNum<int>(strValue);

int intValueFromHex      = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);

إذا تمكنت من استخدام مكتبات Boost (www.boost.org) إلقاء نظرة على مكتبة التحويل - إنه رأس يشمل فقط

#include "boost/lexical_cast.hpp"

ثم كل ما عليك القيام به هو

unsigned long ul = boost::lexical_cast<unsigned long>(str);

جيفري Stedfast لديه وظيفة جميلة حول كتابة الروتين المحللين INT ل Mono (في ج).
يقوم بإنشاء التعليمات البرمجية التي تستخدمها أنواعا أصلية (تحتاج إلى 32 بت لتحليل 32 بت) ورموز الأخطاء لفيضان.

استخدام "ATOL" وظيفة STD المبنية

على سبيل المثال STD :: سلسلة الإدخال = "1024"؛

STD :: ATOL (INPUT.C_STR ())؛

تتوقع ATOL أن تكون المعلمة من نوع سلسلة C، لذلك c_str () هل ذلك من أجلك.

طريقة قوية سوف تكتب وظيفة ثابتة واستخدامها

bool str2Ulong(const string& str,unsigned long & arValue)
{
   char *tempptr=NULL;
   arValue=strtoul(str,tempptr,10);

   return ! (arValue==0 && tempptr==str.c_str());

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