2012-03-04 16 views
8

मैं सी ++ सीख रहा हूं और वर्तमान में मैं स्ट्रिंग्स और पॉइंटर्स के साथ काम कर रहा हूं।सी ++ तार और पॉइंटर्स

मैं एक व्यायाम किताब अनुसरण कर रहे सवालों मेरे द्वारा बनाए गए में से एक के लिए निम्नलिखित:

#include <iostream> 
#include <string> 

using namespace std; 

int main(void){ 
    string * firstName=nullptr; 
    string * lastName=nullptr; 
    string * displayName=nullptr; 

    cout << "Enter your first name: " << endl; 
    getline(cin,*firstName); 

    cout << "Enter your last name: " << endl; 
    getline(cin,*lastName); 

    displayName=new string; 
    *displayName= *lastName + ", " + *firstName; 

    cout << "Here's the information in a single string: " << displayName; 
    cin.get(); 
    return 0; 
} 

एक बोली का उपयोग करने संकेत के और अधिक मैं इसे एक साथ मिश्रण करने तार और साथ की कोशिश की है में इस कारण से समाधान को और अधिक जटिल बना दिया है। जब मैं इसे चलाता हूं तो मुझे "अनचाहे अपवाद: प्रवेश उल्लंघन स्थान xxxxxxxxx" मिलता है।

क्या कोई अब भी चार सरणी के बजाय पॉइंटर्स और तारों का उपयोग करके इसका समाधान सुझा सकता है (जिसे मैंने पहले ही पता लगाया है कि कैसे करना है)?

+3

आप तार का आवंटन नहीं कर रहे हैं, और फिर आप एक अशक्त सूचक को 'getline()' समारोह ... बस 'स्ट्रिंग * एक्स = nullptr के सभी बदलने के पास; ' 'स्ट्रिंग x;' या 'डिस्प्लेनाम' के साथ आपके द्वारा किए गए तारों को आवंटित करने से पहले 'getline() ' – Yaniro

+1

पर जाने से पहले यदि आप" सी ++ सीखना "शुरू कर रहे हैं, तो आपको कच्चे पॉइंटर्स के पास कहीं भी नहीं जाना चाहिए। वे सी ++ का एक कठिन, उन्नत, विशिष्ट हिस्सा हैं जिन्हें आपको "सामान्य" प्रोग्रामिंग गतिविधियों की आवश्यकता नहीं है। –

+0

यह [वीडियो स्निपेट] (http://www.youtube.com/watch?v=i49_SNt4yfk) जब मैं पॉइंटर्स के बारे में उलझन में था तो हमेशा बहुत प्रेरणादायक था ;-) –

उत्तर

12

इसका कारण यह है कि आप नहीं उन्हें प्रयोग करने से पहले अपने वस्तुओं का आवंटन किया है:

string * firstName = new string(); 
//... 
delete firstName; 

यह भी कहा कि इस स्थिति में संकेत का उपयोग कर, अच्छी तरह से, व्यर्थ के लायक है: मानक सी में स्ट्रिंग वस्तुओं ++ पुस्तकालय का आवंटन ढेर से स्ट्रिंग के लिए डेटा; तार आमतौर पर पॉइंटर्स की एक जोड़ी से कहीं अधिक नहीं होते हैं।

+4

हाहाहा पॉइंटलेस: ') – Rishi

2

यह इस तरह दिखेगा:

int main() 
{ 
    std::string* s = new std::string; 
    std::getline(std::cin, *s); 
    std::cout << *s; 
    delete s; 
} 

लेकिन वहाँ वास्तव में ऐसा है, तो सिर्फ ढेर पर एक सामान्य स्ट्रिंग चर को परिभाषित करने के लिए कोई कारण नहीं है।

0

जब से तुम nullptr उपयोग कर रहे हैं, मुझे लगता है एक पूर्ण विकसित सी ++ 11 समाधान समान रूप से ठीक है:

#include <iostream> 
#include <memory> 
#include <string> 

using namespace std; 

int main(void){ 
    unique_ptr<string> firstName(new string()); 
    unique_ptr<string> lastName(new string()); 
    unique_ptr<string> displayName(new string()); 

    cout << "Enter your first name: " << endl; 
    getline(cin,*firstName); 

    cout << "Enter your last name: " << endl; 
    getline(cin,*lastName); 

    *displayName= *lastName + ", " + *firstName; 

    cout << "Here's the information in a single string: " << *displayName; 
} 

बेशक nullptr का उपयोग नहीं कर रहा था जैसे आप चाहते हैं: आप संसाधनों का आवंटन करने की जरूरत है आप उपयोग करना चाहते हैं।

ध्यान दें कि इन साधारण मामलों में पॉइंटर्स का उपयोग करके पैर में स्वयं को सिंटैक्स-वार और बग-वार दोनों शूट कर रहे हैं।

संपादित मैं कोड (एक भूल कोष्ठक और main की अंतिम पंक्ति पर *), यह सफलतापूर्वक संकलित को सही और जीसीसी 4.7 पर चलता है।

+0

इसके लिए धन्यवाद। मुझे अभी भी xstring फ़ाइल से अनचाहे अपवाद त्रुटि मिलती है। क्या आपको लगता है कि दृश्य स्टूडियो में कोई समस्या है? मुझे सराहना है कि मुझे ऐसा नहीं करना चाहिए, मैं बस इससे दूर चलेगा और स्ट्रिंग का उपयोग करने की मूल बातें तक टिकूंगा। – Dan

+0

@Dan ने कोड को सही किया। – rubenvb

2

मुझे लगता है, आप pointers का उपयोग नहीं करना चाहते हैं। आप पॉइंटर्स के बिना strings के साथ काम कर सकते हैं।

#include <iostream> 
#include <string> 

using namespace std; 

int main(void){ 
    string firstName; 
    string lastName; 
    string displayName; 

    cout << "Enter your first name: " << endl; 
    getline(cin,firstName); 

    cout << "Enter your last name: " << endl; 
    getline(cin,lastName); 

    displayName= lastName + ", " + firstName; 

    cout << "Here's the information in a single string: " << displayName; 
    cin.get(); 
    return 0; 
} 

othewise, यदि आप संकेत की जरूरत है, तो आप चर के लिए स्मृति को आबंटित करने के लिए है:

cout << "Enter your first name: " << endl; 
    firstName = new string(); 
    getline(cin,*firstName); 

... और भिन्नता ऑपरेटर के साथ प्रिंट परिणाम (*):

cout << "Here's the information in a single string: " << *displayName; 
0

पढ़ें 10 commandments of c programming। कुछ कम या ज्यादा आज के devs के लिए अप्रचलित हैं, लेकिन कुछ अभी भी इस तरह एक दूसरे के रूप में महत्वपूर्ण हैं,:

तू, शून्य सूचक का पालन नहीं करोगे अराजकता और पागलपन के लिए अपने अंत में तुमको इंतजार है।

वास्तव में आप यहां क्या कर रहे हैं। आपके पॉइंटर्स कहीं भी इंगित नहीं करते हैं (std::nullptr पर असाइनमेंट देखें)।

इसे ठीक करने के लिए, आपको पॉइंटर को दाएं वर्ग/संरचना का एक नया ऑब्जेक्ट असाइन करना होगा। इसके अलावा, पर बाद में इसे हटाने के लिए मत भूलना:

std::string *myString = new std::string(); // create an object and assign it's address to the pointer 

// do something with it... (this part has been right) 

delete myString; // free the memory used by the object 
2

आप क्योंकि आप संकेत के रूप में तार का उपयोग कर रहे हैं और आप उन्हें आरंभ नहीं कर रहे हैं त्रुटियों हो रही है। ऐसा करने का एक सही तरीका होगा:

#include <iostream> 
#include <string> 

using namespace std; 

int main(void){ 
    string firstName; 
    string lastName; 
    string displayName; 

    cout << "Enter your first name: " << endl; 
    cin >> firstName; 

    cout << "Enter your last name: " << endl; 
    cin >> lastName; 

    displayName = firstname + ' ' + lastName; 


    cout << "Here's the information in a single string: " << displayName << endl; 
    return 0; 
} 

आप वास्तव में तार की ओर इशारा का उपयोग कर सकते हैं, लेकिन वे स्थानीय वस्तु के रूप में इस्तेमाल किया और (, या स्थिरांक संदर्भ यदि आप चाहें) संदर्भ के रूप में चारों ओर पारित होने के लिए होती हैं।

1

एक्सेस उल्लंघन इसलिए है क्योंकि आप एक शून्य सूचक को संदर्भित कर रहे हैं।

अशक्त सूचक यहाँ

string * firstName=nullptr; 

सेट कर दिया जाता है और फिर यहाँ dereferenced

getline(cin,*firstName) 

आप firstname 'बिंदु' कुछ (इस मामले में एक स्ट्रिंग) पर की आवश्यकता है। यहां अपवादों के बिना एक संशोधित संस्करण है।

int main(void){ 
    string * firstName= new string(); 
    string * lastName=new string(); 
    string * displayName=new string(); 

    cout << "Enter your first name: " << endl; 
    getline(cin,*firstName); 

    cout << "Enter your last name: " << endl; 
    getline(cin,*lastName); 

    //displayName=new string; 
    *displayName= *lastName + ", " + *firstName; 

    cout << "Here's the information in a single string: " << displayName->c_str(); 
    cin.get(); 
    return 0; 
} 
+0

हाय, यह अभी भी मुझे एक अनचाहे अपवाद देता है। मैं इस विधि से खुद को बंद कर रहा हूं और आसान मार्ग पर टिकेगा। धन्यवाद – Dan

+0

बस यह पता लगाया कि यह था कि मैं teh प्रोग्राम को ठीक करने के बाद त्रुटि उत्पन्न कर रहा था। बहुत मदद की सराहना करते हैं। – Dan

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