C ++ में std :: string से रिक्त स्थान निकालें


222

C ++ में स्ट्रिंग से रिक्त स्थान निकालने का पसंदीदा तरीका क्या है? मैं सभी पात्रों के माध्यम से लूप कर सकता हूं और एक नया स्ट्रिंग बना सकता हूं, लेकिन क्या कोई बेहतर तरीका है?

जवाबों:


257

एल्गोरिथ्म remove_ifऔर आइसस्पेस का उपयोग करने के लिए सबसे अच्छी बात यह है :

remove_if(str.begin(), str.end(), isspace);

अब एल्गोरिथ्म स्वयं कंटेनर को नहीं बदल सकता (केवल मानों को संशोधित कर सकता है), इसलिए यह वास्तव में चारों ओर के मूल्यों को फेरबदल करता है और एक पॉइंटर को देता है जहां अंत अब होना चाहिए। इसलिए हमें स्ट्रिंग :: इरेज़ को वास्तव में कंटेनर की लंबाई को संशोधित करने के लिए कॉल करना होगा:

str.erase(remove_if(str.begin(), str.end(), isspace), str.end());

हमें यह भी ध्यान देना चाहिए कि डेटा की अधिकांश एक प्रति को remove_if बनाएगा। यहाँ एक नमूना कार्यान्वयन है:

template<typename T, typename P>
T remove_if(T beg, T end, P pred)
{
    T dest = beg;
    for (T itr = beg;itr != end; ++itr)
        if (!pred(*itr))
            *(dest++) = *itr;
    return dest;
}

54
चूँकि 'isspace' में अधिभार है, इसलिए आपको संभवतः :: isspace (C कार्यान्वयन जो एक स्थान नहीं लेता है) का उपयोग करने के लिए सामान्य कोड को अर्हता प्राप्त करने की आवश्यकता होगी या क्रिप्टिक टेम्पलेट तात्कालिकता त्रुटियों के साथ स्वागत किया जाएगा।
Bklyn

4
सभी - उपरोक्त विधि से सावधान रहें (दो एकल लाइनें, टेम्पर्ड संस्करण नहीं, हालांकि इसमें एक ही मुद्दा हो सकता है)। मैंने इसे बिना सही समझे एक प्रोजेक्ट में इस्तेमाल किया। उदाहरण के लिए, यदि आप इसे स्ट्रिंग "1 + 1" पास करते हैं तो यह "1 + 11" देता है। मैंने नीचे @rupello की विधि पर स्विच किया और इस मामले के लिए ठीक काम किया। हैप्पी कोडिंग!
जोबी

6
@ जो उत्तर में स्पष्ट रूप से उल्लेख किया गया है कि आपको eraseबाद में कॉल करने की आवश्यकता है । वह सही परिणाम लौटाएगा।
कोनराड रुडोल्फ

31
-1 का यह उपयोग isspaceमूल 7-बिट ASCII को छोड़कर सभी वर्ण सेटों के लिए UB है। C99 §7.4 / 1। यह मुझे आश्चर्यचकित नहीं करता है कि यह अब तक 71 वोटों की धुन पर अपटेड है, वेरी वेरी एडवाइस होने के बावजूद।
चीयर्स एंड हीथ। -

16
बस दोहराने के लिए, इस उत्तर में कोड isspaceसभी गैर-एएससीआईआई पात्रों के लिए नकारात्मक मान (ईओएफ से अलग) से गुजरता है , जिसके लिए साइन-इन की डिफ़ॉल्ट डिफ़ॉल्ट पसंद है char। इस प्रकार इसका अपरिभाषित व्यवहार होता है । मैं इसे दोहरा रहा हूं क्योंकि मुझे उस तथ्य को शोर में डूबने के एक जानबूझकर प्रयास पर संदेह है।
चीयर्स एंड हीथ। - अल्फ

100
std::string::iterator end_pos = std::remove(str.begin(), str.end(), ' ');
str.erase(end_pos, str.end());

31
मुहावरे को मिटाने / हटाने के लिए मेरा अप-वोट। एक लाइनर में बनाया जा सकता है: str.erase (std :: remove (str.begin) (, str.end (), ''), str.end ());
दिसंबर को Bklyn

11
नोट: आपको <algorithm>काम करने के लिए इसे शामिल करना होगा।
तारा

37

से gamedev

string.erase(std::remove_if(string.begin(), string.end(), std::isspace), string.end());

22
यह मानक-अनुरूप कार्यान्वयन पर संकलित नहीं होगा क्योंकि एसटीडी के स्थानीय-अधिभार के कारण :: आइसस्पेस। आपको :: isspace का उपयोग करने की आवश्यकता होगी या std :: bind2nd के साथ कुछ अपठनीय मशीनीकरण करने की आवश्यकता होगी। क्या सामान्य कोड सुंदर नहीं है?
Bklyn

यह भी ध्यान दें कि यदि कोई भी अक्षर नकारात्मक है (जैसे कि UTF8 char जब char पर हस्ताक्षर किया गया है), का उपयोग ::isspaceयूबी है।
मार्टिन बोनर

30

क्या आप बूस्ट स्ट्रिंग एल्गो का उपयोग कर सकते हैं? http://www.boost.org/doc/libs/1_35_0/doc/html/string_algo/usage.html#id1290573

erase_all(str, " "); 

3
यह remove_if(str.begin(), str.end(), isspace);उल्लेखित मैट प्राइस से धीमा है । मुझे पता नहीं क्यों। वास्तव में, सभी बूस्ट सामान, जिसमें एसटीएल विकल्प होते हैं, समान gcc वाले (मेरे द्वारा परीक्षण किए गए सभी) की तुलना में धीमे होते हैं। उनमें से कुछ बेहद धीमी हैं! (unordered_map आवेषण में 5 गुना तक) हो सकता है कि यह साझा वातावरण के सीपीयू कैश के कारण या ऐसा कुछ है।
ईथरेल


15

आप इस समाधान का उपयोग चार को हटाने के लिए कर सकते हैं:

#include <algorithm>
#include <string>
using namespace std;

str.erase(remove(str.begin(), str.end(), char_to_remove), str.end());

1
#include <string.h> नेमस्पेस std का उपयोग;
स्लैक्टमार्ट

यह समाधान मेरे लिए सही है। शीर्ष एक नहीं है।
जेसन लियू

1
नेमस्पेस std का उपयोग करने से बचना चाहिए। stackoverflow.com/questions/1452721/…
अनंत

12

हाय, आप ऐसा कुछ कर सकते हैं। यह फ़ंक्शन सभी रिक्त स्थान को हटा देता है।

string delSpaces(string &str) 
{
   str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
   return str;
}

मैंने एक और फ़ंक्शन किया, जो सभी अनावश्यक रिक्त स्थान को हटा देता है।

string delUnnecessary(string &str)
{
    int size = str.length();
    for(int j = 0; j<=size; j++)
    {
        for(int i = 0; i <=j; i++)
        {
            if(str[i] == ' ' && str[i+1] == ' ')
            {
                str.erase(str.begin() + i);
            }
            else if(str[0]== ' ')
            {
                str.erase(str.begin());
            }
            else if(str[i] == '\0' && str[i-1]== ' ')
            {
                str.erase(str.end() - 1);
            }
        }
    }
    return str;
}

8
string replaceinString(std::string str, std::string tofind, std::string toreplace)
{
        size_t position = 0;
        for ( position = str.find(tofind); position != std::string::npos; position = str.find(tofind,position) )
        {
                str.replace(position ,1, toreplace);
        }
        return(str);
}

इसका इस्तेमाल करें:

string replace = replaceinString(thisstring, " ", "%20");
string replace2 = replaceinString(thisstring, " ", "-");
string replace3 = replaceinString(thisstring, " ", "+");

7

यदि आप इसे आसान मैक्रो के साथ करना चाहते हैं, तो यहां एक है:

#define REMOVE_SPACES(x) x.erase(std::remove(x.begin(), x.end(), ' '), x.end())

यह आपने निश्चित रूप से किया #include <string>है।

इसे ऐसे कॉल करें:

std::string sName = " Example Name ";
REMOVE_SPACES(sName);
printf("%s",sName.c_str()); // requires #include <stdio.h>

5
आप इसके लिए मैक्रो का उपयोग क्यों करेंगे?
दानी

1
एक सामान्य कार्य के लिए कम कीबोर्ड टाइपिंग।
वोलोमाइक

3
कॉल-साइट के लिए समान रूप से छोटा एक फ़ंक्शन को एक स्ट्रिंग के लिए एक lvalue-reference ले रहा है। मैक्रोज़ के पास उनके तर्कों (साइड इफेक्ट्स के साथ एस्प) के साथ बातचीत करने वाले आश्चर्यजनक व्यवहार हो सकते हैं, लेकिन इससे भी बदतर, अगर वे एक त्रुटि में शामिल हैं, तो उनके नाम संकलक संदेशों में नहीं दिखते हैं, उनका कार्यान्वयन करता है।
क्रिस उज्दाविनस

2

मैंने लंबे समय तक नीचे दिए गए काम का उपयोग किया - इसकी जटिलता के बारे में निश्चित नहीं।

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return (f==' '||s==' ');}),s.end());

जब आप हटाना चाहते हैं चरित्र ' 'और उदाहरण के लिए कुछ का - उपयोग करें

s.erase(std::unique(s.begin(),s.end(),[](char s,char f){return ((f==' '||s==' ')||(f=='-'||s=='-'));}),s.end());

इसी तरह ||अगर आपके द्वारा हटाए गए पात्रों की संख्या 1 नहीं है तो बढ़ाएं

लेकिन जैसा कि दूसरों ने उल्लेख किया है कि मिटाना मुहावरे भी ठीक लगता है।


1
string removeSpaces(string word) {
    string newWord;
    for (int i = 0; i < word.length(); i++) {
        if (word[i] != ' ') {
            newWord += word[i];
        }
    }

    return newWord;
}

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


1
   #include <algorithm>
   using namespace std;

   int main() {
       .
       .
       s.erase( remove( s.begin(), s.end(), ' ' ), s.end() );
       .
       .
   }

स्रोत:

इस मंच से लिया गया संदर्भ ।


1
यह वास्तव में पहले से ही इस जवाब से ज्यादा कुछ नहीं जोड़ता है। क्या आपके उत्तर को उच्च गुणवत्ता और इस प्रश्न पर रखने के लायक बनाने के लिए अधिक स्पष्टीकरण या विवरण है?
दास_गीक

मुझे लगता है कि यह अधिक सरल है , 'क्योंकि यह एक बयान में एक ही बात करता है।
जॉन

2
महान! फिर उस तर्क को अपने उत्तर में सीधे स्पष्टीकरण के रूप में रखें । मूल प्रश्न ग्यारह साल से अधिक पुराना है , और औचित्य के बिना आपके उत्तर को अन्य स्वीकृत, अच्छी तरह से उत्कीर्ण उत्तरों की तुलना में शोर के रूप में देखा जा सकता है। उस स्पष्टीकरण के आने से आपके उत्तर को हटाए जाने में मदद मिलेगी।
दास_गीक

यही कारण है कि हो सकता है अच्छा है, लेकिन मैं नहीं मिल सका है कि कैसे मैं रखना चाहिए कि मेरा उत्तर में ... कि मेरा उत्तर से बेहतर है इस सवाल का जवाब? यदि आप मेरे उत्तर को संपादित कर सकते हैं तो यह बहुत खुशी की बात होगी ।
जॉन

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

0

C ++ 20 में आप फ्री फंक्शन std :: erase का उपयोग कर सकते हैं

std::string str = " Hello World  !";
std::erase(str, ' ');

पूर्ण उदाहरण:

#include<string>
#include<iostream>

int main() {
    std::string str = " Hello World  !";
    std::erase(str, ' ');
    std::cout << "|" << str <<"|";
}

मैं छापता हूँ | ताकि यह स्पष्ट हो कि भीख मांगने की जगह को भी हटा दिया गया है।

नोट: यह केवल स्थान को हटाता है, हर दूसरे संभावित चरित्र को नहीं जिसे व्हाट्सएप माना जा सकता है, https://en.cppreference.com/w/cpp/string/byte/isspace देखें


0

सभी व्हाट्सएप पात्रों को हटाता है जैसे टैब और लाइन ब्रेक (C ++ 11):

string str = " \n AB cd \t efg\v\n";
str = regex_replace(str,regex("\\s"),"");

आप एक दशक से अधिक समय से @ मैट-प्राइस के स्वीकृत जवाब पर इस दृष्टिकोण की सिफारिश क्यों करेंगे?
जेरेमी कैनी

सभी समाधान यहां प्रस्तुत किए जाएं। शायद किसी को इस समाधान की आवश्यकता होगी।
AnselmRu

मैं उसके खिलाफ बहस नहीं कर रहा हूं। मैं कह रहा हूं कि लोगों को मतभेदों की व्याख्या करके और विभिन्न परिदृश्यों के लिए बेहतर दृष्टिकोण का आकलन करना आसान हो सकता है।
जेरेमी कैनी

1
संभवतः यह समाधान सबसे अधिक किफायती नहीं है, लेकिन यह आपको सभी व्हाट्सएप पात्रों '\' से छुटकारा पाने की अनुमति देता है , न कि केवल रिक्त स्थान ''।
AnselmRu


-1
string removespace(string str)
{    
    int m = str.length();
    int i=0;
    while(i<m)
    {
        while(str[i] == 32)
        str.erase(i,1);
        i++;
    }    
}

3
यह आमतौर पर पसंद किया जाता है कि आप कोड उत्तरों के लिए एक संक्षिप्त स्पष्टीकरण जोड़ते हैं।
आर्सीक्वेरी

1
@test - length()रिटर्न एक size_t, न कि एक interase()एक size_type, एक नहीं लेता है int। इंडेक्स हमेशा इंक्रीमेंट होने के बाद से लगातार दो स्पेस का सामना करने पर फ़ंक्शन विफल हो जाएगा। यदि एक स्थान को हटा दिया जाता है, तो लूप स्ट्रिंग की सीमा से परे पढ़ेगा। आपको शायद इस उत्तर को हटा देना चाहिए क्योंकि इसमें बहुत मदद की ज़रूरत है।
jww

-3

मुझे डर है कि यह सबसे अच्छा उपाय है जिसके बारे में मैं सोच सकता हूं। लेकिन आप चीजों को थोड़ा बढ़ाने के लिए पहले से आवश्यक न्यूनतम मेमोरी को आरक्षित करने के लिए आरक्षित () का उपयोग कर सकते हैं। आप एक नए तार के साथ समाप्त होंगे जो संभवतः कम होगा लेकिन वह समान मात्रा में मेमोरी लेता है, लेकिन आप वास्तविकताओं से बचेंगे।

संपादित करें: आपकी स्थिति के आधार पर, यह आसपास के पात्रों की तुलना में कम ओवरहेड को उकसा सकता है।

आपको अलग-अलग तरीकों की कोशिश करनी चाहिए और देखना चाहिए कि आपके लिए सबसे अच्छा क्या है: आपके पास कोई भी प्रदर्शन समस्या नहीं हो सकती है।


remove_if प्रत्येक मान की अधिकतम एक प्रति बनाता है। तो वहाँ वास्तव में नहीं है कि क्या किया जाना चाहिए की तुलना में बहुत उपरि।
मैट प्राइस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.