2013-01-09 2 views
21

C++에서 쉽게 무엇을 켜려면 :제거 공백 : 문자열

이 표준 : : 문자열

\t\tHELLO WORLD\r\nHELLO\t\nWORLD  \t 

을 속으로 : std::remove_if

HELLOWORLDHELLOWORLD 
+1

@ tomislav-maric 나는 그 게시물의 복제본이라고 생각하지 않는다. OP는 'cin'스트림으로 작업 중이었고 따라서 iostream 함수를 사용했다. –

+0

유사하지만 정확한 복제는 아니므로 닫을 수 없습니다. – CashCow

+0

@CashCow 나는 그것을 다시 확인했다. 당신 말이 맞아요, 미안 해요. – tmaric

답변

33

간단한 조합 std::string::erase.

안전한 버전 아니 완전히 안전 버전

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

<char> 교체

std::bind(std::isspace<char>, _1, std::locale::classic()) 

대체 문자 유형에서 작동하는 버전에 대한

(모든 관련 헤더를 포함)

::isspace 교체 <ElementType> 또는 템플릿 문자 유형이 무엇이든간에 물론 로켈을 다른 것으로 바꿀 수도 있습니다. 그렇게한다면, 로케일 패싯을 너무 많이 재현하는 비효율을 피하기 위해주의하십시오. 코멘트에서 언급 한대로 : 당신은 Boost.Algorithmerase_all

#include <boost/algorithm/string/erase.hpp> 
#include <iostream> 
#include <string> 

int main() 
{ 
    std::string s = "Hello World!"; 
    // or the more expensive one-liner in case your string is const 
    // std::cout << boost::algorithm::erase_all_copy(s, " ") << "\n"; 
    boost::algorithm::erase_all(s, " "); 
    std::cout << s << "\n"; 
} 

주를 사용할 수

[](char ch) { return std::isspace<char>(ch, std::locale::classic()); } 
+0

@chris':: isspace'에는 새로운 기능이 포함되어 있습니다. 뿐만 아니라 라인 : http://www.cplusplus.com/reference/cctype/isspace/ –

+0

것입니다. isspace는 개행에 대해 true를 리턴합니다. – CashCow

+4

'isspace'는 기본 무언가를 제외하고 모든 문자에 대해 UB를가집니다. C99 §7.4/1. –

2

: C에서

는 ++ (11)는 함께 람다에 안전한 버전을 만들 수 있습니다 : trim_copy (또는 그 사촌 trim_copy_lefttrim_copy_right)은 문자열의 시작과 끝에서 공백 만 제거합니다.

+0

Boost를 사용한 몇 가지 솔루션을 보았지만 'trim'함수 이후가 아니기 때문에 'XX ___ XX_' ->'XX_XX'인데 반해 최종 해결책은'XXXX'가되고 싶습니다. –

+0

@ Mr.Smith Tnx 업데이트. – TemplateRex

11

C++ 03

struct RemoveDelimiter 
{ 
    bool operator()(char c) 
    { 
    return (c =='\r' || c =='\t' || c == ' ' || c == '\n'); 
    } 
}; 

std::string s("\t\tHELLO WORLD\r\nHELLO\t\nWORLD  \t"); 
s.erase(std::remove_if(s.begin(), s.end(), RemoveDelimiter()), s.end()); 

또는 사용 C++ 11 람다

s.erase(std::remove_if(s.begin(), s.end(), 
    [](char c){ return (c =='\r' || c =='\t' || c == ' ' || c == '\n');}), s.end()); 

PS합니다. Erase-remove idiom이 사용됩니다.

1

문자를 사용하여 문자 단위로 이동하고 string::erase()을 사용하면 정상적으로 작동합니다. 당신이 사용하는 것보다 람다을 대신 사용할 수있는 C++ 11에서

void removeWhitespace(std::string& str) { 
    for (size_t i = 0; i < str.length(); i++) { 
     if (str[i] == ' ' || str[i] == '\n' || str[i] == '\t') { 
      str.erase(i, 1); 
      i--; 
     } 
    } 
} 
+1

인접한 공백 문자가있는 경우 작동하지 않습니다. 첫 번째 파일은 지워지고 두 번째 파일은 'i'위치로 내려갑니다. 그런 다음 루프를 돌면서 'i'를 증가시키고 두 번째를 결코 체크하지 않습니다. –

+0

당신 말이 맞아요. 고쳤다. – SelectricSimian

2

C++ 11

std::string input = "\t\tHELLO WORLD\r\nHELLO\t\nWORLD  \t"; 

auto rs = std::regex_replace(input,std::regex("\\s+"), ""); 

std::cout << rs << std::endl; 

/tmp를 ❮❮❮ ./play

HELLOWORLDHELLOWORLD 
3

std :: bind :

str.erase(
    std::remove_if(str.begin(), str.end(), 
     [](char c) -> bool 
     { 
      return std::isspace<char>(c, std::locale::classic()); 
     }), 
    str.end());