2010-07-09 25 views
5

मान लीजिए मैं एक चार सरणी के प्रारंभ निम्नलिखित है:एक तरह से चार सरणियों आरंभ स्ट्रिंग शाब्दिक आरंभ करने के लिए इसी

char charArray[]={'h','e','l','l','o',' ','w','o','r','l','d'}; 

और मैं भी एक स्ट्रिंग शाब्दिक का आरंभीकरण निम्नलिखित है:

char stringLiteral[]="hello world"; 

पहली सरणी और दूसरी स्ट्रिंग की सामग्री के बीच एकमात्र अंतर यह है कि दूसरी स्ट्रिंग को इसके अंत में एक शून्य चरित्र मिला है।

जब यह चार सरणी शुरू करने की बात है, तो क्या कोई मैक्रो या ऐसा कुछ है जो हमें हमारे प्रारंभिक पाठ को दो डबल उद्धरण चिह्नों के बीच रखने की अनुमति देता है, लेकिन जहां सरणी को अतिरिक्त शून्य समाप्त करने वाला चरित्र नहीं मिलता है?

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

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

मैं आपके उत्तरों के लिए आभारी हूं।

+0

@ माइकल - यह सी और सी ++ मानकों में एक आवश्यकता है। – Steve314

+1

* समस्या का सामना करने वाला * यह है कि एनयूएल समाप्त होने वाली भाषा द्वारा "उद्धृत तार" की आवश्यकता होती है। – torak

उत्तर

0

मैं मैं क्या चाहते करने के लिए हालांकि यह सीधे नहीं है मैं चाहता था एक रास्ता मिल गया हो सकता है, लेकिन यह संभवतः एक ही प्रभाव है।
पहले दो निम्नलिखित वर्गों पर विचार करें:

template <size_t size> 
class Cont{ 
public: 
    char charArray[size]; 
}; 
template <size_t size> 
class ArrayToUse{ 
public: 
    Cont<size> container; 
    inline ArrayToUse(const Cont<size+1> & input):container(reinterpret_cast<const Cont<size> &>(input)){} 
}; 

आगे बढ़ने से पहले, आप here जाना और निरंतर अभिव्यक्ति निर्माणकर्ता और आरंभीकरण प्रकारों पर एक नज़र लेने के लिए चाहते हो सकता है।
अब निम्नलिखित कोड को देखो:

const Cont<12> container={"hello world"}; 
ArrayToUse<11> temp(container); 
char (&charArray)[11]=temp.container.charArray; 

अंत में प्रारंभकर्ता पाठ दो डबल कोटेशन के बीच लिखा है।

+0

सुनिश्चित करें कि उस निर्माण के आसपास कुछ टिप्पणियां छिपाने के लिए सुनिश्चित करें। जैसा कि आपने पहले से ही अन्य उत्तरों और टिप्पणियों से अनुमान लगाया होगा, ** ** ** समाप्त नहीं होने वाला '\ 0' एक असामान्य अवधारणा है और उचित चेतावनी संकेतों के साथ आना चाहिए। – DevSolar

+0

@DevSolar: सराहना की – Pooria

3

आप जो चाहते हैं उसे करने का कोई तरीका नहीं है। सरणी को प्रारंभ करने का पहला तरीका प्रत्येक चरित्र के लिए अलग प्रारंभकर्ता निर्दिष्ट करता है, जो स्पष्ट रूप से '\ 0' को छोड़ देता है। दूसरा एक वर्ण स्ट्रिंग से एक वर्ण सरणी शुरू कर रहा है, जिसमें सी/सी ++ में हमेशा एक शून्य चरित्र द्वारा समाप्त किया जाता है।

संपादित करें: ठीक किया: 'चरित्र सूचक' - सी में, तार अशक्त समाप्त कर दिया जाता -> 'चरित्र सरणी'

+2

दरअसल, मैं दूसरे मामले को बेकार नहीं करता हूं, एक चरित्र स्ट्रिंग के लिए पॉइंटर शुरू कर रहा है। यह एक सरणी बना रहा है और स्ट्रिंग की सामग्री के आधार पर इसकी सामग्री शुरू कर रहा है। और हाँ अंतर वास्तव में मायने रखता है। – torak

+0

ने "अलग वर्ण प्रारंभकर्ता" अवधारणा को कभी नहीं देखा, धन्यवाद – Pooria

0

बुनियादी जवाब यह है कि चार सरणियों के विशाल बहुमत के तार कर रहे हैं। सी ++ ने उस सम्मेलन को विरासत में मिला। यहां तक ​​कि जब उस नल की आवश्यकता नहीं होती है, तब भी ज्यादातर समय यह किसी समस्या को छोड़ने में कोई समस्या नहीं है।

मैक्रोज़ आप जो चाहते हैं उसे करने के लिए पर्याप्त शक्तिशाली नहीं हैं। टेम्पलेट्स होंगे, सिवाय इसके कि उनके पास कोई संकलन-समय स्ट्रिंग हैंडलिंग नहीं है।

आमतौर पर, जब लोग समान चर-सरणी अनुक्रम में संख्यात्मक बाइट्स और स्ट्रिंग अक्षर को मिश्रित करना चाहते हैं, तो वे स्ट्रिंग अक्षर का उपयोग करते हैं लेकिन हेक्स वर्ण का उपयोग \xFF जैसे बचते हैं।

6

यह समाप्त '\0'

char c[3] = "foo"; 

कॉपी किए बिना इस प्रकार सरणी घोषित करने के लिए है, जो इसे प्रारंभ हो जाएगा सी में अनुमति दी गई है लेकिन यह सी में गैरकानूनी है ++। मुझे एक चाल के बारे में पता नहीं है जो इसे सी ++ के लिए अनुमति देगा। सी ++ मानक आगे

तर्क: जब इन गैर-समाप्त किए गए सरणी मानक स्ट्रिंग दिनचर्या द्वारा छेड़छाड़ की जाती हैं, तो बड़ी आपदा की संभावना होती है।
मूल सुविधा पर प्रभाव: अर्थात् अच्छी तरह से परिभाषित सुविधा का विलोपन।
परिवर्तित करने में कठिनाई: अर्थपूर्ण परिवर्तन। सरणी को '\ 0' को समाप्त करने वाली स्ट्रिंग को रखने के लिए एक तत्व को बड़ा घोषित किया जाना चाहिए।
का उपयोग कितनी व्यापक रूप से किया जाता है: शायद ही कभी। सरणी प्रारंभिकरण की यह शैली खराब कोडिंग शैली के रूप में देखी जाती है।

+1

मुझे बस आपका जवाब थोड़ा उलझन में मिला। 'चार सी [4] =" foo "; 'शून्य चरित्र सही है? क्या यह अभी भी खराब कोडिंग शैली है? 'Char [128] =" "; 'के बारे में कैसे? केवल एक बफर शुरू करना? क्या यह सब ठीक है? या 'char [128] = {'\ 0'} है; बेहतर? – nus

+0

रैंडल अल्बर्ट द्वारा संदर्भ पुस्तक के अनुसार, 'char c [4] = "foo";' आपके लिए एक शून्य चरित्र रखता है और पुस्तक के अनुसार इसे 'char [4] = "foo" के रूप में लिखने की अनुशंसा की जाती है। ; '। 'char c [3] =" foo ";' अवैध है क्योंकि हमें पीछे की ओर शून्य अक्षर को समाप्त करने के लिए एक जगह आरक्षित करने की आवश्यकता है। – user3437460

+0

@user मेरे पूरे उत्तर को पढ़ने के लायक है जो कहता है "सरणी को एक तत्व को घोषित किया जाना चाहिए जिसमें स्ट्रिंग टर्मिनिंग '\ 0' हो।" –

0

litb has the technically correct answer

एक राय के रूप में - मैं बस अतिरिक्त '\ 0' के 'अपशिष्ट' के साथ रहता हूं। इतनी सारी बग कोड का नतीजा है कि एक समाप्ति नल की उम्मीद है जहां कोई नहीं है (यह सलाह सिर्फ एक या दो दिन पहले दी गई किसी अन्य सलाह के खिलाफ सीधे प्रतीत हो सकती है, जो पूरे बफर को शून्य से परेशान नहीं करता है। मेरा दावा है कि वहां कोई नहीं है विरोधाभास - मैंने अभी भी बफर में स्ट्रिंग को समाप्त करने की वकालत की वकालत की है)।

यदि आप वास्तव में '\ 0' टर्मिनेटर के साथ नहीं रह सकते हैं क्योंकि डेटा संरचना में कुछ अर्थशास्त्र के कारण आप काम कर रहे हैं, जैसे कि यह कुछ बड़ी पैक संरचना का हिस्सा हो सकता है, तो आप हमेशा सरणी में प्रवेश कर सकते हैं अपने आप को (जो मुझे लगता है कि संकलक आप के लिए किया है हो सकता है की तुलना में कम कुशल होना चाहिए):

#define MY_STRING_LITERAL "hello world" 

char stringLiteral[sizeof(MY_STRING_LITERAL) - 1]; 

memcpy(stringLiteral, MY_STRING_LITERAL, sizeof(stringLiteral)); 
+0

मुझे लगता है कि आपकी विधि स्वचालित स्टोरेज क्लास के साथ चार एरे के लिए कंपाइलर के रूप में कुशल होनी चाहिए, लेकिन स्थैतिक स्टोरेज क्लास या ग्लोबल स्कोप वाले वाले चार सरणी के लिए मुझे लगता है कि कंपाइलर द्वारा कोई रन-टाइम प्रतिलिपि नहीं है। – Pooria

+0

@ garrett2011: यह संभवतः 'const char []' आइटम्स के लिए सच है, लेकिन मुझे लगता है कि अक्सर गैर-कॉन्स एरे के प्रारंभिक मान प्रोग्राम छवि 'टेक्स्ट' (जो अधिकांश प्लेटफ़ॉर्म पर गैर-लिखने योग्य) से कॉपी किए जाते हैं 'मुख्य()' से पहले रैम का आह्वान किया जाता है। जब तक 'memcpy() 'केवल एक बार किया जाता है, दक्षता के अनुसार यह एक से अधिक छः दर्जन है, चाहे वह रनटाइम या आपके कोड द्वारा किया जाता है। –

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