2013-01-09 64 views
21

在C++中,有什么简单的方法来打开:删除空白:: string的

此的std :: string

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

分为:

HELLOWORLDHELLOWORLD 
+1

@ tomislav-maric我不认为它是该帖子的副本,OP有一个'cin'流,因此使用iostream函数。 –

+0

类似但不完全重复,所以没有投票结束。 – CashCow

+0

@CashCow我再次检查..你是对的,抱歉。 – tmaric

回答

33

简单的std::remove_if组合std::string::erase

不是完全安全的版本

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

更安全的版本

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

(包括所有相关的标题)

对于使用替代字符类型工作的版本来替换::isspace替换为<char><ElementType>或任何您的模板字符类型。你当然也可以用不同的语言环境替换。如果这样做,请注意避免重复创建区域设置方面的低效率。

在C++ 11可以使更安全的版本为lambda有:

[](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

你可以使用的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"; 
} 

注:如在评论中提到: trim_copy(或其堂兄弟trim_copy_lefttrim_copy_right)只能从字符串的开头和结尾删除空格。

+0

我看到了一些解决方案,用于升压,但我不是一个'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()应该可以正常工作。

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

在C++ 11可以使用的λ,而不是使用std :: bind:

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