2009-05-07 10 views
16

आप एक हस्ताक्षरित चार * की लंबाई कैसे निर्धारित करते हैं?आप एक हस्ताक्षरित चार * की लंबाई कैसे निर्धारित करते हैं?

+2

अधिकतर उत्तर "लंबाई" के अर्थ को निर्दिष्ट करने की आवश्यकता को इंगित करते हैं: तत्वों की संख्या, सूचकांक का आकार सूचक, या क्या आप (हस्ताक्षरित?) वर्णों को शून्य समाप्त स्ट्रिंग का जिक्र कर रहे हैं? – xtofl

उत्तर

21

सूचक के वास्तविक आकार के लिए:

size_t s = sizeof(unsigned char*); 

आप स्ट्रिंग की लंबाई चाहते हैं:

unsigned char* bla = (unsigned char*)"blabla"; 
int s = strlen((char*)bla); 
+5

"ब्लब्ला" केवल पढ़ने-योग्य स्ट्रिंग उत्पन्न करता है, इसलिए ब्लै को बिना हस्ताक्षरित चार * होना चाहिए। –

+2

यह संकलित नहीं होना चाहिए। "ब्लैब्ला" एक कॉन्स char * है, और आप कास्टिंग के बिना एक हस्ताक्षरित चार * को एक कॉन्स char * असाइन नहीं कर सकते हैं। –

+0

यह असाइनमेंट नहीं है - यह प्रारंभिकरण है - हर समय किया जाता है। –

-3

अहस्ताक्षरित चार तक * मैं आपको लगता है कि सूचक पर स्थित स्ट्रिंग मतलब लगता है। उस स्थिति में यह होगा:

strlen(your_string_pointer) 

हालांकि, यह केवल \ 0 स्थिति ही मिलेगा। कोई आवंटन नहीं है यह वास्तविक आवंटित स्मृति ब्लॉक आकार है।

+0

http: //www.cplusplus.com/reference/clibrary/cstring/strlen ... strlen एक "const char *" लेता है, एक हस्ताक्षरित नहीं। – xtofl

8

इसके लिए दो अर्थ हो सकते हैं। क्या आप सिर्फ यह जानना चाहते हैं कि पॉइंटर प्रकार कितना बड़ा है? यदि ऐसा है तो Joce के जवाब सही

size_t size = sizeof(unsigned char*); 

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

हालांकि अगर यह सिर्फ हस्ताक्षर किए गए चार के लिए एक सूचक है जिसका सी शैली स्ट्रिंग से कोई संबंध नहीं है, तो आप जो भी खोज रहे हैं उसे विश्वसनीय रूप से प्राप्त करने का कोई तरीका नहीं है। सी/सी ++ एक लम्बे क्षेत्र को एक सूचक के साथ संबद्ध नहीं करता है। आपको पॉइंटर के साथ लंबाई को पारित करने या वेक्टर जैसे वर्ग का उपयोग करने की आवश्यकता होगी जो सूचक और लंबाई दोनों को संग्रहीत करता है।

+1

आप आवंटित लंबाई को पुनः प्राप्त करने में सक्षम नहीं होने के बारे में सही हैं - कई लोगों की आंखों में एक खराब भाषा डिजाइन निर्णय। आप दो अर्थ होने के बारे में गलत हैं: ऐसा हो सकता है कि आपको निहित शून्य-समाप्त स्ट्रिंग की लंबाई जानने की आवश्यकता हो, हालांकि यह एक हस्ताक्षरित char का उपयोग करना बेहतर होगा। इसे ढाई बनाओ :) – xtofl

0

क्या आप सूचक की लंबाई चाहते हैं, जो एक int होगा। यदि आप उस स्ट्रिंग की लंबाई चाहते हैं जिस पर ध्यान दिया जा रहा है, तो स्ट्रेल का उपयोग करें: उदा। सूचक की आकार: sizeof (अहस्ताक्षरित चार *) स्ट्रिंग के आकार: strlen (अहस्ताक्षरित चार *) multibyte वर्ण ..multi बाइट के रूप में रिपोर्ट मिल जाएगा

+1

असल में यह आकार_t – Tom

+0

दाएं हो। मुझे size_t कहा जाना चाहिए था – Rohit

0

आप सी उपयोग कर रहे हैं ++, और उसके एक स्ट्रिंग एक हस्ताक्षरित चार * में, आप इसे पहले छेड़छाड़ करने से पहले इसे std :: स्ट्रिंग में डालकर बेहतर कर सकते हैं। इस तरह आप इसे सभी प्रकार की चीजें कर सकते हैं और फिर भी जब चाहें लंबाई() और/या क्षमता() प्राप्त कर पाएंगे।

मुझे लगता है कि आप अपने आकार को गैर-स्थिर बनाने के लिए सरणी कहने के लिए चीजें कर रहे हैं। यदि आप बस आवंटित, सेटिंग और भूल रहे हैं, तो आप हमेशा एक अलग चर में सरणी के वास्तविक आवंटन आकार को स्टोर कर सकते हैं - या बेहतर, संरचना/कक्षा बनाएं।

//WARNING: memory issues not addressed here. 
struct myStringStruct 
{ 
    unsigned char * string; 
    int len; 

    allocate(int size) { 
    len = size; 
    string = malloc(sizeof(unsigned char) * len); 
    } 
} 
किसी भी है कि तुलना में अधिक जटिल

और आप फिर से खोज करने std :: स्ट्रिंग कर रहे हैं।

6

एक आदर्श दुनिया में, आप नहीं करते हैं। आप सी * स्टाइल स्ट्रिंग्स (जो एनयूएल-टर्मिनेटेड हैं और आप लंबाई को माप सकते हैं) के लिए char * का उपयोग करते हैं, और केवल बाइट डेटा के लिए हस्ताक्षरित char * (जो इसकी लंबाई के साथ दूसरे पैरामीटर में आता है या जो भी हो, और जो आप शायद अंदर आते हैं एक एसटीएल कंटेनर ASAP, जैसे vector<unsigned char> या basic_string<unsigned char>)।

मूल समस्या यह है कि आप पोर्टेबल धारणाएं नहीं बना सकते हैं कि चार और हस्ताक्षरित चार का भंडारण प्रतिनिधित्व समान है या नहीं। वे आमतौर पर होते हैं, लेकिन उन्हें होने की अनुमति नहीं है। तो कोई स्ट्रिंग-जैसी लाइब्रेरी फ़ंक्शंस नहीं हैं जो बिना हस्ताक्षर किए गए char * पर काम करती हैं, केवल char * पर संचालित होती हैं, और हस्ताक्षर किए गए char * पर हस्ताक्षर किए गए char * को कास्ट करना सामान्य रूप से सुरक्षित नहीं होता है और परिणाम को स्ट्रिंग के रूप में देखते हैं। चूंकि चार पर हस्ताक्षर किए जा सकते हैं, इसका मतलब है कि कोई कास्टिंग हस्ताक्षरित char * char * पर नहीं है।

हालांकि, 0 हमेशा हस्ताक्षरित चार और चार में समान मान प्रतिनिधित्व होता है। तो एक गैर-आदर्श दुनिया में, यदि आपके पास कहीं से सी-स्टाइल स्ट्रिंग है लेकिन यह एक हस्ताक्षरित चार * के रूप में पहुंचा है, तो आप (ए) इसे char * पर डालें और इसके साथ आगे बढ़ें, लेकिन भी (बी) यह पता लगाएं कि यह आपको किसने किया, और उनसे रोकने के लिए कृपया पूछें।