2016-03-09 6 views
5

एक समय में एक सी-शैली स्ट्रिंग में एक इनपुट इनपुट को पढ़ना पसंद है। आप सेट आकार के साथ पहले चार सरणी बनाने के बिना ऐसा कैसे करते हैं (आप नहीं जानते कि उपयोगकर्ता कितने अक्षर दर्ज करेगा)। और चूंकि आप सरणी का आकार बदल नहीं सकते हैं, यह कैसे किया जाता है? मैं इन पंक्तियों के साथ कुछ सोच रहा था, लेकिन यह काम नहीं करता है।सी ++ सी-स्टाइल स्ट्रिंग में एक बार में एक char में पढ़ा जाता है? सी ++ आईडी में

char words[1]; 
int count = 0; 

char c; 
while(cin.get(c)) 
{ 
    words[count] = c; 
    char temp[count+1]; 
    count++; 
    words = temp; 
    delete[] temp; 
} 
+4

शब्द सरणी 1 बाइट लंबी है ...... सी स्टाइल स्ट्रिंग में कम से कम 2 बाइट्स होना चाहिए: एक चरित्र के लिए 1 और 'पूर्ण' समाप्ति के लिए 2 एसडी होना चाहिए। – LPs

+2

केवल 'हटाएं' जो आप 'नया' करते हैं, और केवल 'हटाएं []' जिसे आप नया करते हैं [] '। चूंकि आप गतिशील रूप से 'temp' आवंटित नहीं करते हैं, इसलिए आपको इसे मुक्त नहीं करना चाहिए। –

उत्तर

6

चूंकि आप std::vector का उपयोग नहीं कर सकते हैं, मुझे लगता है कि आप std::string का उपयोग नहीं कर सकते हैं। यदि आप std::string का उपयोग कर सकते हैं, तो आप समाधान the answer by @ilia द्वारा प्रदान कर सकते हैं।

  1. एक सूचक है कि गतिशील स्मृति आवंटित की ओर इशारा का उपयोग करें:

    कि बिना, आपके ही एकमात्र विकल्प है।

  2. आवंटित सरणी के आकार का ट्रैक रखें। यदि वर्णों को संग्रहीत करने के लिए संख्या वर्तमान आकार से अधिक है, सरणी आकार बढ़ाएं, नई मेमोरी आवंटित करें, पुरानी मेमोरी से सामग्री को नई मेमोरी में कॉपी करें, पुरानी मेमोरी हटाएं, नई मेमोरी का उपयोग करें।
  3. फ़ंक्शन के अंत में आवंटित स्मृति हटाएं।

यहाँ मैं क्या सुझाव है कि है:

#include <iostream> 

int main() 
{ 
    size_t currentSize = 10; 

    // Always make space for the terminating null character. 
    char* words = new char[currentSize+1]; 
    size_t count = 0; 

    char c; 
    while(std::cin.get(c)) 
    { 
     if (count == currentSize) 
     { 
     // Allocate memory to hold more data. 
     size_t newSize = currentSize*2; 
     char* temp = new char[newSize+1]; 

     // Copy the contents from the old location to the new location. 
     for (size_t i = 0; i < currentSize; ++i) 
     { 
      temp[i] = words[i]; 
     } 

     // Delete the old memory. 
     delete [] words; 

     // Use the new memory 
     words = temp; 
     currentSize = newSize; 
     } 

     words[count] = c; 
     count++; 
    } 

    // Terminate the string with a null character. 
    words[count] = '\0'; 

    std::cout << words << std::endl; 

    // Deallocate the memory. 
    delete [] words; 
} 
2

आपने सी-शैली सरणी के लिए कहा। ढेर या गतिशील आवंटन इस मामले में आपकी सेवा नहीं करेगा। प्रत्येक बार जब आप नया तत्व जोड़ते हैं तो आपको सरणी संख्या की गिनती को बदलने की आवश्यकता होती है जो स्वचालित रूप से संभव नहीं है। प्रत्येक बार जब कोई नया chae पढ़ा जाता है तो आपको चारों ओर काम करना और सरणी को हटाना और आरक्षित करना होगा। तो अगर आप विकल्पों के लिए है:

  1. उपयोग std::vector (जो इस उद्देश्य के लिए बनाया गया था)
  2. डुप्लिकेट क्या std :: वेक्टर के अंदर है और अपने कोड के दौरान यह अपने आप को लिखने (जो भयानक लगती है)

std::vector समाधान:

std::vector<char> words; 
words.reserve(ESTIMATED_COUNT); // if you you do not the estimated count just delete this line 
char c; 
while(cin.get(c)){ 
    words.push_back(c); 
} 
+0

लेकिन उन्होंने सी-स्टाइल स्ट्रिंग के लिए कहा, हालांकि मैं 'std :: vector' का उपयोग करना पसंद करता हूं, और हम 'std :: vector ' का उपयोग कर सकते हैं' char * ' – deepmax

+0

@deepmax की एक और प्रस्तुति है मैंने अभी देखा है –

+0

वेक्टर का उपयोग करना अच्छा होगा, लेकिन कक्षा में मैं ले रहा हूं हम वेक्टर को कवर नहीं करते हैं, इसलिए किसी भी असाइनमेंट पर इसकी अनुमति नहीं दी जाएगी। –

1

आप दो तरह से है, पहले एक शून्य आकार सरणी का उपयोग करने, प्रत्येक इनपुट के बाद आप सरणी और alloca हटाना है एक नया है जो +1 बड़ा है, फिर इनपुट स्टोर करें। यह कम स्मृति का उपयोग करता है लेकिन अक्षम है। (सी में, आप दक्षता में सुधार के लिए realloc का उपयोग कर सकते हैं)

दूसरा बफर का उपयोग करना है, उदाहरण के लिए आप एक निश्चित आकार सरणी में इनपुट पढ़ते हैं और जब यह पूर्ण हो जाता है, तो आप मुख्य सरणी के अंत में बफर जोड़ते हैं (हटाने और पुनः आवंटित करके)।

वैसे, आप std::vector का उपयोग कर सकते हैं जो स्वयं के आकार को स्वचालित रूप से और कुशलता से बढ़ाता है।

+0

पहला विकल्प 'realloc' का उपयोग कर थोड़ा सुव्यवस्थित किया जा सकता है। – Henrik

+0

@ हेनरिक: सी हां में, लेकिन सी ++ में मुझे यकीन नहीं है कि 'realloc' समर्थित है या नहीं। – deepmax

+0

हां, 'cstdlib' – Henrik

2
#include <iostream> 
#include <string> 
using namespace std; 

int main() 
{ 
    string s1; 
    char c; 
    while (cin.get(c)) 
    { 
     if (c == '\n') 
      continue; 
     s1 += c; 
     cout << "s1 is: " << s1.c_str() << endl; //s1.c_str() returns c style string 
    } 
} 
+0

से यह एक सी-शैली स्ट्रिंग नहीं है – deepmax

+0

s1.c_str() वापसी सी शैली स्ट्रिंग – ilia

1

आप सी शैली तार तो प्रयोग पर सेट कर रहे हैं:

char* words; 
int count = 0; 

char c; 
while(cin.get(c)) 
{ 
    // Create a new array and store the value at the end. 
    char* temp = new char[++count]; 
    temp[count - 1] = c; 

    // Copy over the previous values. Notice the -1. 
    // You could also replace this FOR loop with a memcpy(). 
    for(int i = 0; i < count - 1; i++) 
     temp[i] = words[i]; 

    // Delete the data in the old memory location. 
    delete[] words; 

    // Point to the newly updated memory location. 
    words = temp; 
} 

मैं क्या Humam Helfawi सुझाव दिया करते हैं और std::vector<char> का उपयोग आप सी ++ का उपयोग कर रहे के बाद होता है, यह आपके जीवन आसान हो जाएगा। उपरोक्त कार्यान्वयन मूल रूप से वेक्टर का कम सुरुचिपूर्ण संस्करण है। यदि आप हाथ से पहले आकार नहीं जानते हैं तो आपको स्मृति का आकार बदलना होगा।

0

आप मनमाने ढंग से आकार के एक स्ट्रिंग बफर आवंटित की जरूरत है। फिर, यदि संलग्न करने पर अधिकतम संख्या में वर्ण प्राप्त किए जाते हैं, तो आपको बफर को रीयलॉक के साथ विस्तारित करने की आवश्यकता है।

प्रत्येक चरित्र पर कॉलल रीयलोक से बचने के लिए, जो इष्टतम नहीं है, विकास रणनीति की सिफारिश की जाती है, जैसे प्रत्येक आवंटन में आकार को दोगुना करना। प्लेटफॉर्म पर निर्भर होने वाली और भी बढ़िया विकास रणनीतियां हैं।

फिर, अंत में, यदि आप आवश्यक हो तो बफर को सटीक बाइट्स की सटीक संख्या में ट्रिम करने के लिए रीयलोक का उपयोग कर सकते हैं।

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