2010-02-23 9 views
5

मैं सी में perl के chomp() फ़ंक्शन के एक eqivilent संस्करण को कार्यान्वित करने का प्रयास कर रहा हूं और मैं एक कोने मामले में आया हूं जहां तर्क के रूप में पारित एक स्ट्रिंग शब्दकोष सेगमेंटेशन गलती होगी (ठीक है तो)।सी में एक समारोह के लिए एक स्ट्रिंग अक्षर के गुजरने का पता लगाने के लिए कैसे?

उदाहरण chomp("some literal string\n");

वहाँ शाब्दिक मौसम का पता लगाने या मेरे कार्य नहीं करने के लिए C99 में एक परिभाषित रास्ता एक स्ट्रिंग पारित किया गया था है, ताकि मैं return कर सकते हैं यह NUL के लिए बाहर का प्रयास करने के बिना?

char* chomp(char *s) 
{ 
    char *temp = s; 

    if (s && *s) 
    { 
     s += strlen(s) - 1; 
     if (*s == '\n') 
     { 
      *s = '\0'; 
     } 
    } 
    return temp; 
} 
+2

विषम। क्या आपका कंपाइलर एक स्ट्रिंग शाब्दिक को एक तर्क के रूप में पारित नहीं किया जाना चाहिए जिसे 'const char *' के रूप में घोषित नहीं किया गया है? –

+0

@ एडम मारस: यह मानक द्वारा आवश्यक नहीं है। हालांकि, इसे संशोधित करने की कोशिश यूबी है। – dirkgently

+2

एडम मारस: सादा सी में, स्ट्रिंग अक्षर में 'char *' टाइप किया गया है, न कि 'const char * '। – caf

उत्तर

5

क्या सी 99 में गीलेर का पता लगाने के लिए एक परिभाषित तरीका है या नहीं, मेरा कार्य एक स्ट्रिंग शाब्दिक पारित किया गया था ताकि मैं इसे एनयूएल के प्रयास किए बिना वापस कर सकूं?

आपको नहीं करना चाहिए।

आपकी एपीआई को कॉलर के लिए चीजों को झुकाव करने का प्रयास नहीं करना चाहिए, केवल बाद में इसे तोड़ना है। यदि कॉलर नियमों को तोड़ता है, तो उन्हें वहां और वहां पता लगाना चाहिए।

यदि कॉलर किसी फ़ंक्शन में एक गैर-परिवर्तनीय स्ट्रिंग पास करता है जो एक उत्परिवर्ती की अपेक्षा करता है, तो segfault होना चाहिए। कुछ और खराब डिजाइन है।

(परिशिष्ट:। सबसे अच्छा डिजाइन, ज़ाहिर है, स्ट्रिंग है कि फोन करने वाले को मुक्त कराने के लिए जिम्मेदार है की एक प्रति वापस जाने के लिए होगा)

+1

क्या कॉलर को अलर्ट करने के लिए प्रलेखन के अलावा कोई अनुशंसित अभ्यास है कि यदि यह 'मुक्त() 'डी नहीं है तो यह संभावित मेमोरी लीक हो सकता है? – SiegeX

+1

@ घेराबंदी - एक चीज जो मुझे करना पसंद है उनमें उन कार्यों के नामों में आवंटन शामिल है जो 'char * chomp_alloc (const char *) करते हैं; ' –

+0

@ घेराबंदी: मैं' error_t chomp (const char * input, char ** out_result) 'खुद। यह स्पष्ट है कि इसमें कुछ ऐसा आ रहा है जो सिंटैक्स के लिए नहीं है, इसलिए स्पष्ट रूप से आपको इसे मुक्त करना होगा, और आपको एक विशिष्ट त्रुटि भी मिल जाएगी। –

3

आपका chomp आदर्श रूप से एक नई स्ट्रिंग बनाना चाहिए और इसे वापस करना चाहिए। यह निर्धारित करने का कोई तरीका नहीं है कि क्या आप एक स्ट्रिंग को शाब्दिक पारित कर चुके हैं या नहीं। वास्तव में, मैं chomp निम्नलिखित हस्ताक्षर उपयोग करने का सुझाव चाहते हैं:

char *chomp(const char *s); /* do not modify input parameters */ 

या, आप दो अलग अलग कार्यों बना सकते हैं और ग्राहकों के लिए उन्हें दस्तावेज़ सकता है: शाब्दिक तार के लिए गैर शाब्दिक के लिए chomp और chompl का उपयोग करें।

+0

क्या कॉलर को अलर्ट करने के लिए प्रलेखन के अलावा कोई अनुशंसित अभ्यास है कि यदि यह 'मुक्त() 'डी नहीं है तो यह संभावित मेमोरी लीक हो सकता है? – SiegeX

+0

बिल्कुल नहीं। जब आप इस ऑब्जेक्ट का उपयोग कर रहे हों तो आप कभी कैसे जानेंगे? उदाहरण के लिए 'strdup' दस्तावेज़ देखें। – dirkgently

1

एक बहुत जोखिम भरा/बुरा रास्ता => आमतौर पर स्ट्रिंग-शाब्दिक नहीं है केवल पढ़ने के लिए डेटा खंड में संग्रहीत हैं। तो एक तरीका गंतव्य स्ट्रिंग पर लिखने का प्रयास करना है - यदि segmentation faultsignal callback में प्राप्त किया गया है - तो इसका मतलब है कि आपकी स्ट्रिंग शाब्दिक है, और longjmp के साथ परीक्षण फ़ंक्शन पर वापस लौटें। कुछ की तरह:

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <setjmp.h> 

static jmp_buf jbuf; 

static void catch_segv() { 
    longjmp(jbuf, 1); 
} 

int isLiteral(char * ptr) { 
    if (setjmp(jbuf) == 0) 
    return (*ptr = *ptr, 0); 
    else 
    return 1; 
    } 

int main() 
{ 
    char writableString[] = "some writable string"; 

    signal(SIGSEGV, catch_segv); 

    printf("is literal = %d\n", isLiteral(writableString)); 
    printf("is literal = %d\n", isLiteral("read-only string")); 

    return 0; 
} 

लेकिन यह देखते हुए कि SIGSEGV के बाद कार्यक्रम शुरू करने के लिए बहुत जोखिम भरा काम है और यह देखते हुए कि स्ट्रिंग शाब्दिक हमेशा केवल पढ़ने के लिए डेटा अनुभाग पर संग्रहीत नहीं कर रहे हैं - इस समाधान अत्यधिक अन-सिफारिश की उत्पादन के लिए है।

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

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