2009-09-27 17 views
5

सी ++ में किसी स्ट्रिंग से हस्ताक्षरित लंबे समय तक पुनर्प्राप्त करने का सबसे सुरक्षित और सर्वोत्तम तरीका क्या है?आप स्ट्रिंग से एक हस्ताक्षरित लंबे समय तक कैसे प्राप्त करते हैं?

मुझे कई संभावित तरीकों के बारे में पता है।

सबसे पहले, एटोल से लिया गया एक हस्ताक्षरित लंबा रूपांतरित करना।

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

इसके साथ स्पष्ट समस्या यह है कि, क्या होता है जब मेरे एसआरटी में संग्रहीत मूल्य एक हस्ताक्षरित लंबे समय से बड़ा हो सकता है? एटोल पुनर्प्राप्त क्या करता है?

अगली संभावना स्ट्रेटल का उपयोग करना है।

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

हालांकि, यह मेरी आवश्यकताओं के लिए थोड़ा अधिक जटिल है। मैं एक साधारण फ़ंक्शन, स्ट्रिंग इन, हस्ताक्षरित लम्बी बेस 10 आउट करना चाहता हूं। इसके अलावा, त्रुटि प्रबंधन वांछित होने के लिए बहुत छोड़ देता है।

मुझे मिली अंतिम संभावना एसएसकेएनएफ का उपयोग करना है।

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 अन्य विकल्प क्या ढूंढने में विफल रहे हैं? सी ++ एसडीडी लाइब्रेरी में कोई चीज जो एक स्ट्रिंग को एक हस्ताक्षरित लंबे समय तक परिवर्तित कर देगी और विफलता पर अपवाद फेंक देगी?

मेरी माफी माँगती है कि यह एक डुप्ली है, लेकिन मुझे कोई प्रश्न नहीं मिला जो वास्तव में मेरा मिलान करता था।

+0

'एटोल':" यदि सही मूल्य प्रतिनिधित्व मूल्यों की सीमा से बाहर है, तो LONG_MAX या LONG_MIN वापस आ गया है। " http://www.cplusplus.com/reference/clibrary/cstdlib/atol/ –

+0

युगल प्रश्न, मुझे यकीन नहीं है कि वे डुप्लीकेट हैं या नहीं: (1) http://stackoverflow.com/questions/1243428/convert- स्ट्रिंग-टू-इंट-टू-बूल-असफल-इन-सी/1243435 (2) http://stackoverflow.com/questions/1435253/c-syntax-question-if-var-type-int/1435268 – GManNickG

+3

मैं नहीं करता समझ में नहीं आता कि आपके पास स्ट्रेटल के खिलाफ क्या है। यह इसके लिए एकदम सही काम है। आधार के लिए 0 पास करें और यह आपकी सी लाइब्रेरी समझने वाले किसी भी बेस उपसर्ग स्ट्रिंग के साथ संख्याओं को परिवर्तित करेगा, जैसे "0x"। –

उत्तर

5

एक तरह से यह करने के लिए:

stringstream(str) >> ulongVariable; 
+0

मैंने इस सवाल को और स्पष्ट करने के लिए प्रश्न संपादित किया कि मैं इस मामले में सी-स्टाइल स्ट्रिंग के साथ काम कर रहा हूं। तो यह स्ट्रीमस्ट्रीम होना चाहिए (स्ट्रिंग (myStr)) >> ulongvariable। जो मुझे अपर्याप्त लगता है:/मैं बल्कि कुछ साफ और अधिक सीधे आगे था। –

+1

असल में, यह आवश्यक नहीं है क्योंकि 'std :: string' का एक अंतर्निहित कन्स्ट्रक्टर है जो एक पैरामीटर के रूप में सी-शैली स्ट्रिंग लेता है। वह कन्स्ट्रक्टर आपको केवल 'स्ट्रिंगस्ट्रीम ("जो भी") लिखने की अनुमति देता है। – hrnt

+0

* स्मोक स्वयं * बेशक। इसके बावजूद, इसमें दो वर्गों को तत्काल करने का नतीजा है - और इसमें सभी स्मृति प्रबंधन अंतर्निहित हैं - एक आंतरिक लूप के साथ एक सरल कार्य करने में सक्षम होना चाहिए। मेरी इच्छा है कि मानक लाइब्रेरी में कुछ ऐसा बनाया गया हो। –

5

आप कोई समस्या नहीं के साथ strtoul उपयोग कर सकते हैं। फ़ंक्शन एक हस्ताक्षरित लंबा लौटाता है। यदि कनवर्टन फ़ंक्शन रिटर्न 0 नहीं किया जा सकता है। यदि सही लंबा मान सीमा से बाहर है तो फ़ंक्शन वापसी ULONG_MAX और इरनो ग्लोबल वैरिएबल ERANGE पर सेट है।

+0

यदि संभव हो तो इरनो शैली की बजाय अपवाद शैली त्रुटि हैंडलिंग की तलाश में है। –

+0

अपवाद शैली त्रुटि हैंडलिंग लेकिन कक्षाओं के माध्यम से कोई ओवरहेड नहीं है? थोड़ा विरोधाभासी आईएमओ लगता है :) –

+0

ठीक है, कार्य अपवाद शैली त्रुटि हैंडलिंग कर सकते हैं। मैं सिर्फ दो कक्षाओं को तुरंत चालू नहीं करना चाहता हूं जिनकी मुझे हर समय आवश्यकता नहीं है जब मैं एक लंबा रूपांतरित करना चाहता हूं। यह बहुत अपमानजनक लगता है! –

4
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); 
1

Jeffrey Stedfast has a beautiful post मोनो (सी) में int पार्सर रूटीन लिखने के बारे में लिखने के बारे में।
यह कोड उत्पन्न करता है जो देशी प्रकारों का उपयोग करता है (आपको 32 बिट पार्स करने के लिए 32 बिट की आवश्यकता है) और अतिप्रवाह के लिए त्रुटि कोड।

2

यदि आप बूस्ट लाइब्रेरीज़ (www.boost) का उपयोग कर सकते हैं।संगठन) को रूपांतरण पुस्तकालय को देखो - यह एक शीर्ष लेख है केवल शामिल

#include "boost/lexical_cast.hpp" 

तो तुम सब करने की जरूरत है

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

मैं बूस्ट लाइब्रेरीज़ में देखूंगा, मैं पाइथन व्याख्यान लाइब्रेरी का उपयोग करने पर विचार कर रहा था ताकि बूस्ट का उपयोग मेरी आवश्यकताओं के लिए अच्छी तरह से काम कर सके। यह अच्छा होगा अगर इसके लिए एक सरल साफ कार्य था, उन लोगों के लिए जो बूस्ट पुस्तकालयों पर निर्भरता नहीं चाहते हैं। –

0

मजबूत तरीका होगा एक स्थिर समारोह लिख सकते हैं और यह

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

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

} 
का उपयोग करें
+1

उदाहरण गलत है, tempptr (char *) है, strtoul अपेक्षा करता है (char **) – nrathaus

1

"एटोल" इन-बिल्ट स्टडी फ़ंक्शन

उदाहरण के लिए std :: string input = "1024";

std :: atol (input.c_str());

एटोल पैरामीटर प्रकार स्ट्रिंग होने की अपेक्षा करता है, इसलिए c_str() यह आपके लिए करता है।

संबंधित मुद्दे