2010-09-25 10 views
53

atol() & strtol() के बीच क्या अंतर है?एटोल() वी/एस। strtol()

long atol(const char *nptr); 

long int strtol(const char *nptr, char **endptr, int base); 

एक सामान्यीकृत मामले में, जब मैं (base तर्क का उपयोग करने के लिए मैं बस नहीं करना चाहती:

उनके आदमी पृष्ठों के अनुसार, वे मिलान तर्क के साथ ही एक ही प्रभाव है लगता है दशमलव संख्या), मैं किस समारोह का उपयोग करना चाहिए?

उत्तर

77

strtol आपको अधिक लचीलापन प्रदान करता है, क्योंकि यह वास्तव में आपको बता सकता है कि क्या संपूर्ण स्ट्रिंग को पूर्णांक में परिवर्तित किया गया था या नहीं। atol, जब (atol("help") में) की तरह एक नंबर करने के स्ट्रिंग परिवर्तित करने में असमर्थ, रिटर्न 0, जो atol("0") से अप्रभेद्य है:

int main() 
{ 
    int res_help = atol("help"); 
    int res_zero = atol("0"); 

    printf("Got from help: %d, from zero: %d\n", res_help, res_zero); 
    return 0; 
} 

आउटपुट:

Got from help: 0, from zero: 0 

strtol अपने endptr तर्क का उपयोग, निर्दिष्ट करेगा , जहां रूपांतरण विफल रहा।

int main() 
{ 
    char* end; 
    int res_help = strtol("help", &end, 10); 

    if (!*end) 
    printf("Converted successfully\n"); 
    else 
    printf("Conversion error, non-convertible part: %s", end); 

    return 0; 
} 

आउटपुट:

Conversion error, non-convertible part: help 

इसलिए, किसी भी गंभीर प्रोग्रामिंग के लिए, मैं निश्चित रूप से strtol का उपयोग करें। यह उपयोग करने के लिए थोड़ा और मुश्किल है लेकिन जैसा कि मैंने ऊपर बताया है, इसका एक अच्छा कारण है।

atol केवल बहुत ही सरल और नियंत्रित मामलों के लिए उपयुक्त हो सकता है।

+3

मुझे आपके उदाहरण में विश्वास है, स्थिति 'if (! * End)' होना चाहिए। यह स्ट्रिंग के शून्य टर्मिनेटर को इंगित करेगा (यदि यह सब परिवर्तित हो गया था) लेकिन इसे स्वयं को सेट नहीं किया जाएगा। –

+0

@ जेफ एम: आप सही हैं, क्षमा करें टाइपो –

+0

क्या यह वही तर्क लिनक्स कर्नेल फ़ंक्शन 'simple_strtol' पर लागू होता है? मुझे आपके सटीक मॉडल का उपयोग करके 'if (! * End) 'शर्त को सही करने के लिए शर्त नहीं मिल सकती है। –

4

नए कोड में मैं हमेशा strtol का उपयोग करता हूं। इसमें त्रुटि हैंडलिंग है और endptr तर्क आपको यह देखने की अनुमति देता है कि स्ट्रिंग का कौन सा हिस्सा उपयोग किया गया था।

C99 ato* कार्यों के बारे में मानक कहता है:

त्रुटि पर व्यवहार के लिए छोड़कर, वे

atoi: (int)strtol(nptr,(char **)NULL, 10)
atol: strtol(nptr,(char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)

4

atol(str) के बराबर के बराबर है

strtol(str, (char **)NULL, 10); 

उपयोग strtol यदि आप अंत सूचक चाहते हैं (वहाँ पढ़ने के लिए अधिक अक्षर हैं कि क्या जांच करने के लिए या यदि वास्तव में आप किसी भी सब पर पढ़ा है) एक आधार के 10 अन्यथा के अलावा अन्य या, Atol ठीक है।

2

यदि मेमोरी परोसा जाता है, तो strtol() में पहले वर्ण को इंगित करने के लिए (वैकल्पिक) endptr सेट करने के लिए अतिरिक्त लाभ होता है जिसे परिवर्तित नहीं किया जा सकता है। यदि NULL, इसे अनदेखा किया जाता है। इस तरह यदि आप एक स्ट्रिंग को संसाधित कर रहे हैं जिसमें संख्याएं और वर्ण मिश्रित हैं, तो आप जारी रख सकते हैं।

उदा।,

char buf[] = "213982 and the rest"; 
char *theRest; 
long int num = strtol(buf, &theRest, 10); 
printf("%ld\n", num); /* 213982 */ 
printf("%s\n", theRest); /* " and the rest" */ 
20

atol कार्यक्षमता, strtol कार्यक्षमता का एक सबसेट है, सिवाय इसके कि atol कोई प्रयोग करने योग्य त्रुटि हैंडलिंग क्षमताओं के साथ प्रदान करता है। ato... फ़ंक्शंस के साथ सबसे प्रमुख समस्या यह है कि वे अतिप्रवाह के मामले में अपरिभाषित व्यवहार का कारण बनते हैं। नोट: यह किसी त्रुटि के मामले में सूचनात्मक प्रतिक्रिया की कमी नहीं है, यह अपरिभाषित व्यवहार है, यानी आम तौर पर एक अप्राप्य विफलता।

इसका मतलब है कि atol फ़ंक्शन (साथ ही अन्य सभी ato.. फ़ंक्शंस) किसी भी गंभीर व्यावहारिक उद्देश्यों के लिए काफी बेकार है। यह एक डिजाइन गलती थी और इसकी जगह सी इतिहास के जंकयार्ड पर है। रूपांतरण करने के लिए आपको strto... समूह से फ़ंक्शंस का उपयोग करना चाहिए। ato... समूह के कार्यों में अंतर्निहित समस्याओं को ठीक करने के लिए, अन्य चीजों के साथ, उन्हें पेश किया गया था।

18

atoi मैन पेज के अनुसार, इसे strtol द्वारा बहिष्कृत कर दिया गया है।

ERRORS 
    EINVAL (not in C99) The given base contains an unsupported value. 
    ERANGE The resulting value was out of range. 
    The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned). 

रेंज त्रुटियों के लिए निम्न कोड चेक:

IMPLEMENTATION NOTES 
The atoi() and atoi_l() functions have been deprecated by strtol() and strtol_l() 
and should not be used in new code. 
1

strtol मैन ऑफ द पेज निम्नलिखित देता है। (संशोधित एली कोड थोड़ा सा)

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h> 

int main() 
{ 
    errno = 0; 
    char* end = 0; 
    long res = strtol("83459299999999999K997", &end, 10); 

    if(errno != 0) 
    { 
     printf("Conversion error, %s\n", strerror(errno)); 
    } 
    else if (*end) 
    { 
     printf("Converted partially: %i, non-convertible part: %s\n", res, end); 
    } 
    else 
    { 
     printf("Converted successfully: %i\n", res); 
    } 

    return 0; 
}