2011-06-12 17 views
21

मैं सॉफ्टवेयर का एक टुकड़ा लिख ​​रहा हूं, और मुझे libcurl के साथ एक वेबपृष्ठ से प्राप्त डेटा को संभालने की आवश्यकता है। जब मुझे डेटा मिलता है, तो किसी कारण से इसमें अतिरिक्त लाइन ब्रेक होते हैं। मुझे केवल अक्षरों, संख्याओं और रिक्त स्थानों को अनुमति देने का एक तरीका पता लगाने की आवश्यकता है। और लाइन ब्रेक सहित, बाकी सब कुछ हटा दें। क्या ऐसा करने का कोई आसान तरीका है? धन्यवाद।C++ में स्ट्रिंग से सभी गैर अल्फान्यूमेरिक वर्णों को कैसे पट्टी करें?

+0

आप डेटा कैसे भंडारण कर रहे हैं? 'Char' बफर या 'स्ट्रिंग' में? –

उत्तर

3

यदि आप string का उपयोग कर रहे हैं तो आप हमेशा erase सभी गैर अल्फान्यूमेरिक वर्णों को लूप कर सकते हैं।

#include <cctype> 

size_t i = 0; 
size_t len = str.length(); 
while(i < len){ 
    if (!isalnum(str[i]) || str[i] == ' '){ 
     str.erase(i,1); 
     len--; 
    }else 
     i++; 
} 

मानक लिब के साथ बेहतर कोई भी लूप के बिना ऐसा कर सकता है।

तुम सिर्फ एक char बफर का उपयोग कर रहे हैं, तो आप के माध्यम से और यह पीछे की ओर एक (हमलावर चरित्र अधिलेखित करने के लिए) के बाद अगर एक चरित्र अक्षरांकीय नहीं है, सभी पात्रों बदलाव पाश कर सकते हैं:

#include <cctype> 

size_t buflen = something; 
for (size_t i = 0; i < buflen; ++i) 
    if (!isalnum(buf[i]) || buf[i] != ' ') 
     memcpy(buf[i], buf[i + 1], --buflen - i); 
+1

लूप को खत्म करने में [मिटाएं-हटाएं मुहावरे] शामिल होंगे (http://en.wikipedia.org/wiki/Erase-remove_idiom) –

+0

अपने दूसरे मामले में, यदि आप स्रोत और गंतव्य पॉइंटर्स बनाए रखते हैं, तो आप एक memcpy करने से बच सकते हैं हर बार एक चरित्र को हटाने की जरूरत है शेष बफर का। यानी (char * s = buf, * d = buf; * s; ++ s) {if (! isalnum (* s) || * s! = '') * d ++ = * s; } * डी = 0; – Ferruccio

2

remove_copy_if मानक एल्गोरिदम आपके मामले के लिए बहुत उपयुक्त होगा।

bool my_predicate(char c); 

फिर स्ट्रिंग से अवांछित पात्रों को दूर करने के std::remove_if एल्गोरिथ्म का उपयोग करें:

42

एक समारोह है कि एक char लेता है और true रिटर्न आपको लगता है कि चरित्र या false दूर करने के लिए आप इसे रखना चाहते हैं चाहते हैं, तो लिखें :

std::string s = "my data"; 
s.erase(std::remove_if(s.begin(), s.end(), my_predicate), s.end()); 

अपनी आवश्यकताओं के आधार पर, आप, std::isalnum की तरह, मानक पुस्तकालय में से एक predicates उपयोग करने में सक्षम हो सकता है बजाय लेखन की अपनी खुद की भविष्यवाणी (आपने कहा कि आपको अल्फान्यूमेरिक वर्णों और रिक्त स्थान से मिलान करने की आवश्यकता है, इसलिए शायद यह आपको बिल्कुल आवश्यक फिट नहीं करता है)।

आप मानक पुस्तकालय std::isalnum समारोह का उपयोग करना चाहते हैं, तो आप सी स्टैंडर्ड लाइब्रेरी हैडर <cctype> में std::isalnum समारोह को स्पष्ट करने के लिए और सी ++ स्टैंडर्ड में std::isalnum (जो आपके द्वारा उपयोग करना चाहते हैं) एक डाली की आवश्यकता होगी लाइब्रेरी हैडर <locale> (जो आपके द्वारा उपयोग करना चाहते हैं नहीं है, जब तक कि आप स्थान-विशिष्ट स्ट्रिंग प्रसंस्करण प्रदर्शन करने के लिए चाहते हैं):

s.erase(std::remove_if(s.begin(), s.end(), (int(*)(int))std::isalnum), s.end()); 

यह क्रम कंटेनर से किसी के साथ समान रूप से अच्छी तरह से काम करता है (सहित std::string, std::vector और std::deque)। इस मुहावरे को आम तौर पर "मिटा/हटाएं" मुहावरे के रूप में जाना जाता है। std::remove_if एल्गोरिदम सामान्य सरणी के साथ भी काम करेगा। std::remove_if अनुक्रम पर केवल एक ही पास बनाता है, इसलिए इसमें रैखिक समय जटिलता है।

+6

यह करो, मेरा नहीं। –

+2

@ जेम्स: यह विशेष वर्णों के बजाय अल्फा न्यूमेरिक वर्णों को हटा रहा है। क्या मुझसे कुछ गलत हो रही है ? – bjskishore123

+2

यह अल्फान्यूमेरिक वर्णों को हटा देगा और विशेष वर्ण नहीं होगा क्योंकि '(int (*) (int)) std :: isalnum 'जब भी एक अल्फान्यूमेरिक वर्ण का सामना किया जाता है तो' सत्य 'वापस आ जाएगा और वह वर्ण स्ट्रिंग से मिटा दिया जाएगा। –

1

आप निकालना-मिटा एल्गोरिथ्म इस तरह से उपयोग कर सकते हैं -

// Removes all punctuation  
s.erase(std::remove_if(s.begin(), s.end(), &ispunct), s.end()); 
2
#include <cctype> 
#include <string> 
#include <functional> 

std::string s = "Hello World!"; 
s.erase(std::remove_if(s.begin(), s.end(), 
    std::not1(std::ptr_fun(std::isalnum)), s.end()), s.end()); 
std::cout << s << std::endl; 

में परिणाम:

"HelloWorld" 

आप isalnum उपयोग यह निर्धारित करने या नहीं, हर किरदार अल्फा न्यूमेरिक है, तो पर not1 पर फ़ंक्शन को पास करने के लिए ptr_fun का उपयोग करें जो लौटाए गए मान को नहीं देता है, जो आपको केवल अल्फान्यूमेरिक सामग्री के साथ छोड़ देता है।

0

मेरे लिए निम्नलिखित कार्य करता है।

str.erase(std::remove_if(str.begin(), str.end(), &ispunct), str.end()); 
str.erase(std::remove_if(str.begin(), str.end(), &isspace), str.end()); 
0
void remove_spaces(string data) 
{ int i=0,j=0; 
    while(i<data.length()) 
    { 
     if (isalpha(data[i])) 
     { 
     data[i]=data[i]; 
     i++; 
     } 
     else 
      { 
      data.erase(i,1);} 
    } 
    cout<<data; 
} 
1

बस जेम्स McNellis के कोड में थोड़ा और अधिक विस्तार। उनका कार्य गैर-एलनम के बजाय एलनम पात्रों को हटा रहा है।

स्ट्रिंग से गैर-एलनम वर्णों को हटाने के लिए। (Alnum = वर्णमाला या न्यूमेरिक)

  • एक समारोह घोषित (isalnum रिटर्न 0 अगर पारित चार alnum नहीं है)

    bool isNotAlnum(char c) { 
        return isalnum(c) == 0; 
    } 
    
  • और फिर लिखना इस

    s.erase(remove_if(s.begin(), s.end(), isNotAlnum), s.end()); 
    

तो आपकी स्ट्रिंग केवल एलनम पात्रों के साथ है।

1

std::isalnum का पिछला का उपयोग करता है एकल तर्क गुजर बिना std::ptr_fun साथ संकलन नहीं होगा की आवश्यकता है, एक लैम्ब्डा समारोह सही जवाब संपुटित चाहिए साथ इसलिए इस समाधान:

s.erase(std::remove_if(s.begin(), s.end(), 
[](auto const& c) -> bool { return !std::isalnum(c); }), s.end()); 
संबंधित मुद्दे

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