我目前正在使用以下代码来修正程序中的所有std::strings
:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
它工作正常,但我想知道是否有一些可能会失败的最终案例?
当然,欢迎使用优雅替代品和左侧解决方案的答案。
答案 0 :(得分:584)
编辑从c ++ 17开始,标准库的某些部分被删除了。幸运的是,从c ++ 11开始,我们有lambda这是一个很好的解决方案。
#include <algorithm>
#include <cctype>
#include <locale>
// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
return !std::isspace(ch);
}));
}
// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
return !std::isspace(ch);
}).base(), s.end());
}
// trim from both ends (in place)
static inline void trim(std::string &s) {
ltrim(s);
rtrim(s);
}
// trim from start (copying)
static inline std::string ltrim_copy(std::string s) {
ltrim(s);
return s;
}
// trim from end (copying)
static inline std::string rtrim_copy(std::string s) {
rtrim(s);
return s;
}
// trim from both ends (copying)
static inline std::string trim_copy(std::string s) {
trim(s);
return s;
}
感谢https://stackoverflow.com/a/44973498/524503提出现代解决方案。
我倾向于使用这些中的一个来满足我的修剪需求:
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
// trim from start
static inline std::string <rim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
// trim from end
static inline std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
// trim from both ends
static inline std::string &trim(std::string &s) {
return ltrim(rtrim(s));
}
他们相当自我解释并且工作得非常好。
编辑:顺便说一下,我有std::ptr_fun
来帮助消除std::isspace
的歧义,因为实际上有第二个定义支持区域设置。这可能是一个演员也一样,但我倾向于更喜欢这个。
编辑:解决有关通过引用接受参数,修改并返回参数的一些注释。我同意。我可能更喜欢的实现是两组函数,一组用于实现,另一组用于复制。一组更好的例子是:
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
}
// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
}
// trim from both ends (in place)
static inline void trim(std::string &s) {
ltrim(s);
rtrim(s);
}
// trim from start (copying)
static inline std::string ltrim_copy(std::string s) {
ltrim(s);
return s;
}
// trim from end (copying)
static inline std::string rtrim_copy(std::string s) {
rtrim(s);
return s;
}
// trim from both ends (copying)
static inline std::string trim_copy(std::string s) {
trim(s);
return s;
}
我保留上面的原始答案,但是为了保持高投票的答案仍然可用。
答案 1 :(得分:400)
使用Boost's string algorithms最简单:
#include <boost/algorithm/string.hpp>
std::string str("hello world! ");
boost::trim_right(str);
str
现在是"hello world!"
。还有trim_left
和trim
,它们会削减双方。
如果您为上述任何功能名称添加_copy
后缀,例如trim_copy
,该函数将返回字符串的修剪副本,而不是通过引用修改它。
如果您为上述任何功能名称添加_if
后缀,例如trim_copy_if
,您可以修剪满足自定义谓词的所有字符,而不仅仅是空格。
答案 2 :(得分:59)
使用以下代码从std::strings
(ideone)右侧修剪(尾随)空格和制表符:
// trim trailing spaces
size_t endpos = str.find_last_not_of(" \t");
size_t startpos = str.find_first_not_of(" \t");
if( std::string::npos != endpos )
{
str = str.substr( 0, endpos+1 );
str = str.substr( startpos );
}
else {
str.erase(std::remove(std::begin(str), std::end(str), ' '), std::end(str));
}
为了平衡问题,我也会包含左侧修剪代码(ideone):
// trim leading spaces
size_t startpos = str.find_first_not_of(" \t");
if( string::npos != startpos )
{
str = str.substr( startpos );
}
答案 3 :(得分:51)
有点迟到了,但没关系。现在C ++ 11在这里,我们有lambdas和auto变量。所以我的版本,也处理所有空格和空字符串,是:
#include <cctype>
#include <string>
#include <algorithm>
inline std::string trim(const std::string &s)
{
auto wsfront=std::find_if_not(s.begin(),s.end(),[](int c){return std::isspace(c);});
auto wsback=std::find_if_not(s.rbegin(),s.rend(),[](int c){return std::isspace(c);}).base();
return (wsback<=wsfront ? std::string() : std::string(wsfront,wsback));
}
我们可以从wsfront
创建一个反向迭代器,并将其用作第二个find_if_not
中的终止条件,但这仅适用于全空白字符串,而gcc 4.8至少是isn用std::string::const_reverse_iterator
来推断反向迭代器(auto
)的类型是否足够聪明。我不知道构造反向迭代器有多贵,所以YMMV在这里。通过此更改,代码如下所示:
inline std::string trim(const std::string &s)
{
auto wsfront=std::find_if_not(s.begin(),s.end(),[](int c){return std::isspace(c);});
return std::string(wsfront,std::find_if_not(s.rbegin(),std::string::const_reverse_iterator(wsfront),[](int c){return std::isspace(c);}).base());
}
答案 4 :(得分:39)
你正在做的事情很好而且健壮。我已经使用了相同的方法很长时间,我还没有找到更快的方法:
const char* ws = " \t\n\r\f\v";
// trim from end of string (right)
inline std::string& rtrim(std::string& s, const char* t = ws)
{
s.erase(s.find_last_not_of(t) + 1);
return s;
}
// trim from beginning of string (left)
inline std::string& ltrim(std::string& s, const char* t = ws)
{
s.erase(0, s.find_first_not_of(t));
return s;
}
// trim from both ends of string (right then left)
inline std::string& trim(std::string& s, const char* t = ws)
{
return ltrim(rtrim(s, t), t);
}
通过提供要修剪的字符,您可以灵活地修剪非空格字符,并且只能修剪您想要剪裁的字符。
答案 5 :(得分:34)
试试这个,它对我有用。
inline std::string trim(std::string& str)
{
str.erase(0, str.find_first_not_of(' ')); //prefixing spaces
str.erase(str.find_last_not_of(' ')+1); //surfixing spaces
return str;
}
答案 6 :(得分:25)
我喜欢tzaman的解决方案,唯一的问题是它不修剪只包含空格的字符串。
要纠正1个缺陷,请在2条修剪线之间添加str.clear()
std::stringstream trimmer;
trimmer << str;
str.clear();
trimmer >> str;
答案 7 :(得分:19)
std::string trim(const std::string &s)
{
std::string::const_iterator it = s.begin();
while (it != s.end() && isspace(*it))
it++;
std::string::const_reverse_iterator rit = s.rbegin();
while (rit.base() != it && isspace(*rit))
rit++;
return std::string(it, rit.base());
}
答案 8 :(得分:15)
如果是空字符串,则代码假定向string::npos
添加1会给出0. string::npos
类型为string::size_type
,这是无符号的。因此,您依赖于添加的溢出行为。
答案 9 :(得分:14)
std::string choppa(const std::string &t, const std::string &ws)
{
std::string str = t;
size_t found;
found = str.find_last_not_of(ws);
if (found != std::string::npos)
str.erase(found+1);
else
str.clear(); // str is all whitespace
return str;
}
这也适用于null情况。 : - )
答案 10 :(得分:10)
我的解决方案基于answer by @Bill the Lizard。
请注意,如果输入字符串只包含空格,这些函数将返回空字符串。
const std::string StringUtils::WHITESPACE = " \n\r\t";
std::string StringUtils::Trim(const std::string& s)
{
return TrimRight(TrimLeft(s));
}
std::string StringUtils::TrimLeft(const std::string& s)
{
size_t startpos = s.find_first_not_of(StringUtils::WHITESPACE);
return (startpos == std::string::npos) ? "" : s.substr(startpos);
}
std::string StringUtils::TrimRight(const std::string& s)
{
size_t endpos = s.find_last_not_of(StringUtils::WHITESPACE);
return (endpos == std::string::npos) ? "" : s.substr(0, endpos+1);
}
答案 11 :(得分:9)
我的回答是对此帖子的top answer进行了改进,该帖子修剪了控制字符和空格(ASCII table上的0-32和127)。
std::isgraph
确定角色是否具有图形表示,因此您可以使用此方法更改Evan的答案,以从字符串的任一侧删除任何没有图形表示的字符。结果是一个更优雅的解决方案:
#include <algorithm>
#include <functional>
#include <string>
/**
* @brief Left Trim
*
* Trims whitespace from the left end of the provided std::string
*
* @param[out] s The std::string to trim
*
* @return The modified std::string&
*/
std::string& ltrim(std::string& s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::ptr_fun<int, int>(std::isgraph)));
return s;
}
/**
* @brief Right Trim
*
* Trims whitespace from the right end of the provided std::string
*
* @param[out] s The std::string to trim
*
* @return The modified std::string&
*/
std::string& rtrim(std::string& s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::ptr_fun<int, int>(std::isgraph)).base(), s.end());
return s;
}
/**
* @brief Trim
*
* Trims whitespace from both ends of the provided std::string
*
* @param[out] s The std::string to trim
*
* @return The modified std::string&
*/
std::string& trim(std::string& s) {
return ltrim(rtrim(s));
}
注意:或者,如果您需要支持宽字符,则应该能够使用std::iswgraph
,但您还必须编辑此代码以启用std::wstring
操作,这是我尚未测试的内容(请参阅std::basic_string
的参考页面以探索此选项)。
答案 12 :(得分:7)
对于它的价值,这是一个关注性能的修剪实现。它比我见过的许多其他修剪程序要快得多。它使用原始c字符串和索引,而不是使用迭代器和std :: finds。它优化了以下特殊情况:size 0 string(什么都不做),没有要修剪的空格的字符串(什么都不做),只有尾随空格的字符串要修剪(只调整字符串大小),字符串完全是空格(只是清除字符串) 。最后,在最坏的情况下(带有前导空格的字符串),它尽力执行有效的复制构造,只执行1个副本,然后移动该副本代替原始字符串。
void TrimString(std::string & str)
{
if(str.empty())
return;
const auto pStr = str.c_str();
size_t front = 0;
while(front < str.length() && std::isspace(int(pStr[front]))) {++front;}
size_t back = str.length();
while(back > front && std::isspace(int(pStr[back-1]))) {--back;}
if(0 == front)
{
if(back < str.length())
{
str.resize(back - front);
}
}
else if(back <= front)
{
str.clear();
}
else
{
str = std::move(std::string(str.begin()+front, str.begin()+back));
}
}
答案 13 :(得分:7)
mDrawerToggle = new ActionBarDrawerToggle([...]) {
public void onDrawerClosed(View view) {
Log.d(TAG, String.format("% 12d onDrawerClosed", Calendar.getInstance().getTimeInMillis()));
super.onDrawerClosed(view);
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
Log.d(TAG, String.format("% 12d onDrawerSlide %f", Calendar.getInstance().getTimeInMillis(), slideOffset)));
// THIS IS CALLED WITH slideOffset = 0.0f TOO LONG BEFORE onDrawerClosed
super.onDrawerSlide(drawerView, slideOffset);
}
};
答案 14 :(得分:7)
这就是我使用的。只需继续从前面移除空间,然后,如果还剩下任何东西,请从后面做同样的事情。
void trim(string& s) {
while(s.compare(0,1," ")==0)
s.erase(s.begin()); // remove leading whitespaces
while(s.size()>0 && s.compare(s.size()-1,1," ")==0)
s.erase(s.end()-1); // remove trailing whitespaces
}
答案 15 :(得分:7)
使用C ++ 11还有一个regular expression模块,当然可以用来修剪前导或尾随空格。
也许是这样的:
std::string ltrim(const std::string& s)
{
static const std::regex lws{"^[[:space:]]*", std::regex_constants::extended};
return std::regex_replace(s, lws, "");
}
std::string rtrim(const std::string& s)
{
static const std::regex tws{"[[:space:]]*$", std::regex_constants::extended};
return std::regex_replace(s, tws, "");
}
std::string trim(const std::string& s)
{
return ltrim(rtrim(s));
}
答案 16 :(得分:6)
这样做的优雅方式可能就像
std::string & trim(std::string & str)
{
return ltrim(rtrim(str));
}
支持功能实现为:
std::string & ltrim(std::string & str)
{
auto it = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( str.begin() , it);
return str;
}
std::string & rtrim(std::string & str)
{
auto it = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( it.base() , str.end() );
return str;
}
一旦你完成了所有这些,你也可以写下这个:
std::string trim_copy(std::string const & str)
{
auto s = str;
return ltrim(rtrim(s));
}
答案 17 :(得分:5)
修剪C ++ 11实现:
static void trim(std::string &s) {
s.erase(s.begin(), std::find_if_not(s.begin(), s.end(), [](char c){ return std::isspace(c); }));
s.erase(std::find_if_not(s.rbegin(), s.rend(), [](char c){ return std::isspace(c); }).base(), s.end());
}
答案 18 :(得分:4)
我想如果你开始要求修剪字符串的“最佳方法”,我会说一个好的实现将是:
显然,有太多不同的方法来解决这个问题,这肯定取决于你真正需要什么。但是,C标准库在&lt; string.h&gt;中仍然有一些非常有用的函数,就像memchr一样。有一个原因使C仍然被认为是IO的最佳语言 - 它的stdlib是纯粹的效率。
inline const char* trim_start(const char* str)
{
while (memchr(" \t\n\r", *str, 4)) ++str;
return str;
}
inline const char* trim_end(const char* end)
{
while (memchr(" \t\n\r", end[-1], 4)) --end;
return end;
}
inline std::string trim(const char* buffer, int len) // trim a buffer (input?)
{
return std::string(trim_start(buffer), trim_end(buffer + len));
}
inline void trim_inplace(std::string& str)
{
str.assign(trim_start(str.c_str()),
trim_end(str.c_str() + str.length()));
}
int main()
{
char str [] = "\t \nhello\r \t \n";
string trimmed = trim(str, strlen(str));
cout << "'" << trimmed << "'" << endl;
system("pause");
return 0;
}
答案 19 :(得分:4)
在C ++ 17中,您可以使用basic_string_view::remove_prefix和basic_string_view::remove_suffix:
std::string_view trim(std::string_view s) const
{
s.remove_prefix(std::min(s.find_first_not_of(" \t\r\v\n"), s.size()));
s.remove_suffix((s.size() - 1) - std::min(s.find_last_not_of(" \t\r\v\n"), s.size() - 1));
return s;
}
答案 20 :(得分:3)
error: current bson type is an array and not a document
答案 21 :(得分:3)
这是我的版本:
size_t beg = s.find_first_not_of(" \r\n");
return (beg == string::npos) ? "" : in.substr(beg, s.find_last_not_of(" \r\n") - beg);
答案 22 :(得分:3)
由于添加了back()
和pop_back()
,因此可以在C ++ 11中更简单地完成此操作。
while ( !s.empty() && isspace(s.back()) ) s.pop_back();
答案 23 :(得分:3)
我不确定你的环境是否相同,但在我的情况下,空字符串大小写会导致程序中止。我要用if(!s.empty())包装那个erase调用,或者如前所述使用Boost。
答案 24 :(得分:3)
以下是我提出的建议:
std::stringstream trimmer;
trimmer << str;
trimmer >> str;
流提取会自动消除空白,因此这就像魅力一样 如果我自己这么说的话,也很干净优雅。 ;)
答案 25 :(得分:3)
为噪音贡献我的解决方案。 trim
默认创建一个新字符串并返回修改后的字符串,而trim_in_place
修改传递给它的字符串。 trim
函数支持c ++ 11移动语义。
#include <string>
// modifies input string, returns input
std::string& trim_left_in_place(std::string& str) {
size_t i = 0;
while(i < str.size() && isspace(str[i])) { ++i; };
return str.erase(0, i);
}
std::string& trim_right_in_place(std::string& str) {
size_t i = str.size();
while(i > 0 && isspace(str[i - 1])) { --i; };
return str.erase(i, str.size());
}
std::string& trim_in_place(std::string& str) {
return trim_left_in_place(trim_right_in_place(str));
}
// returns newly created strings
std::string trim_right(std::string str) {
return trim_right_in_place(str);
}
std::string trim_left(std::string str) {
return trim_left_in_place(str);
}
std::string trim(std::string str) {
return trim_left_in_place(trim_right_in_place(str));
}
#include <cassert>
int main() {
std::string s1(" \t\r\n ");
std::string s2(" \r\nc");
std::string s3("c \t");
std::string s4(" \rc ");
assert(trim(s1) == "");
assert(trim(s2) == "c");
assert(trim(s3) == "c");
assert(trim(s4) == "c");
assert(s1 == " \t\r\n ");
assert(s2 == " \r\nc");
assert(s3 == "c \t");
assert(s4 == " \rc ");
assert(trim_in_place(s1) == "");
assert(trim_in_place(s2) == "c");
assert(trim_in_place(s3) == "c");
assert(trim_in_place(s4) == "c");
assert(s1 == "");
assert(s2 == "c");
assert(s3 == "c");
assert(s4 == "c");
}
答案 26 :(得分:2)
上述方法很棒,但有时您希望将一组函数用于您的例程所认为的空白。在这种情况下,使用仿函数来组合操作会变得混乱,所以我更喜欢一个简单的循环,我可以为修剪修改。这是在SO上从C版本复制的略微修改的修剪函数。在此示例中,我正在修剪非字母数字字符。
string trim(char const *str)
{
// Trim leading non-letters
while(!isalnum(*str)) str++;
// Trim trailing non-letters
end = str + strlen(str) - 1;
while(end > str && !isalnum(*end)) end--;
return string(str, end+1);
}
答案 27 :(得分:1)
这个怎么样??
#include <iostream>
#include <string>
#include <regex>
std::string ltrim( std::string str ) {
return std::regex_replace( str, std::regex("^\\s+"), std::string("") );
}
std::string rtrim( std::string str ) {
return std::regex_replace( str, std::regex("\\s+$"), std::string("") );
}
std::string trim( std::string str ) {
return ltrim( rtrim( str ) );
}
int main() {
std::string str = " \t this is a test string \n ";
std::cout << "-" << trim( str ) << "-\n";
return 0;
}
注意:我还是比较新的C ++,所以如果我不在这里,请原谅我。
答案 28 :(得分:1)
好吧,这可能不是最快的,但是...很简单。
str = " aaa ";
int len = str.length();
// rtrim
while(str[len-1] == ' ') { str.erase(--len,1); }
// ltrim
while(str[0] == ' ') { str.erase(0,1); }
答案 29 :(得分:1)
这是一个易于理解的解决方案,适合初学者不习惯在任何地方写std::
但尚不熟悉const
- 正确性,iterator
s,STL algorithm
等等...
#include <string>
#include <cctype> // for isspace
using namespace std;
// Left trim the given string (" hello! " --> "hello! ")
string left_trim(string str) {
int numStartSpaces = 0;
for (int i = 0; i < str.length(); i++) {
if (!isspace(str[i])) break;
numStartSpaces++;
}
return str.substr(numStartSpaces);
}
// Right trim the given string (" hello! " --> " hello!")
string right_trim(string str) {
int numEndSpaces = 0;
for (int i = str.length() - 1; i >= 0; i--) {
if (!isspace(str[i])) break;
numEndSpaces++;
}
return str.substr(0, str.length() - numEndSpaces);
}
// Left and right trim the given string (" hello! " --> "hello!")
string trim(string str) {
return right_trim(left_trim(str));
}
希望它有所帮助...
答案 30 :(得分:1)
又一个选项 - 从两端删除一个或多个字符。
string strip(const string& s, const string& chars=" ") {
size_t begin = 0;
size_t end = s.size()-1;
for(; begin < s.size(); begin++)
if(chars.find_first_of(s[begin]) == string::npos)
break;
for(; end > begin; end--)
if(chars.find_first_of(s[end]) == string::npos)
break;
return s.substr(begin, end-begin+1);
}
答案 31 :(得分:1)
这是一个直接的实施。对于这样一个简单的操作,您可能不应该使用任何特殊构造。内置的isspace()函数负责处理各种形式的白色字符,因此我们应该利用它。您还必须考虑字符串为空或只是一堆空格的特殊情况。向左或向右修剪可以从以下代码派生。
string trimSpace(const string &str) {
if (str.empty()) return str;
string::size_type i,j;
i=0;
while (i<str.size() && isspace(str[i])) ++i;
if (i == str.size())
return string(); // empty string
j = str.size() - 1;
//while (j>0 && isspace(str[j])) --j; // the j>0 check is not needed
while (isspace(str[j])) --j
return str.substr(i, j-i+1);
}
答案 32 :(得分:1)
由于我想用C ++ 11方法更新旧的C ++ trim函数,我已经测试了很多已发布的问题答案。我的结论是我保留了旧的C ++解决方案!
它是最快的一个,甚至添加更多字符来检查(例如\ r \ n我看到没有用于\ f \ v的用例)仍然比使用算法的解决方案更快。
std::string & trimMe (std::string & str)
{
// right trim
while (str.length () > 0 && (str [str.length ()-1] == ' ' || str [str.length ()-1] == '\t'))
str.erase (str.length ()-1, 1);
// left trim
while (str.length () > 0 && (str [0] == ' ' || str [0] == '\t'))
str.erase (0, 1);
return str;
}
答案 33 :(得分:1)
此版本修剪了内部空白和非字母数字:
static inline std::string &trimAll(std::string &s)
{
if(s.size() == 0)
{
return s;
}
int val = 0;
for (int cur = 0; cur < s.size(); cur++)
{
if(s[cur] != ' ' && std::isalnum(s[cur]))
{
s[val] = s[cur];
val++;
}
}
s.resize(val);
return s;
}
答案 34 :(得分:0)
C ++ 11:
int i{};
string s = " h e ll \t\n o";
string trim = " \n\t";
while ((i = s.find_first_of(trim)) != -1)
s.erase(i,1);
cout << s;
输出:
hello
也适用于空字符串
答案 35 :(得分:0)
这有什么好处? (因为这篇文章完全需要另一个答案:)
string trimBegin(string str)
{
string whites = "\t\r\n ";
int i = 0;
while (whites.find(str[i++]) != whites::npos);
str.erase(0, i);
return str;
}
trimEnd的类似情况,只需反转极化指数。
答案 36 :(得分:0)
我知道这是一个非常老的问题,但是我向您的代码添加了几行,并且从两端清除了空白。
void trim(std::string &line){
auto val = line.find_last_not_of(" \n\r\t") + 1;
if(val == line.size() || val == std::string::npos){
val = line.find_first_not_of(" \n\r\t");
line = line.substr(val);
}
else
line.erase(val);
}
答案 37 :(得分:0)
下面是一遍(可能是两遍)解决方案。它两次遍历字符串的空白部分,一次遍历非空白部分。
void trim(std::string& s) {
if (s.empty())
return;
int l = 0, r = s.size() - 1;
while (l < s.size() && std::isspace(s[l++])); // l points to first non-whitespace char.
while (r >= 0 && std::isspace(s[r--])); // r points to last non-whitespace char.
if (l > r)
s = "";
else {
l--;
r++;
int wi = 0;
while (l <= r)
s[wi++] = s[l++];
s.erase(wi);
}
return;
}
答案 38 :(得分:0)
std::string trim( std::string && str )
{
size_t end = str.find_last_not_of( " \n\r\t" );
if ( end != std::string::npos )
str.resize( end + 1 );
size_t start = str.find_first_not_of( " \n\r\t" );
if ( start != std::string::npos )
str = str.substr( start );
return std::move( str );
}
答案 39 :(得分:0)
这是使用正则表达式修剪的解决方案
TIMEOUT = 7 # number of seconds your want for timeout
keycode ="0000";
count = 3
def interrupted(signum, frame):
"called when read times out"
print ('Input timeout!! Contacting Owner!')
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
count = 3
for i in range(3,0,-1):
userIn= raw_input("Enter the security code to disable the alarm
system\n");
if userIn != keycode :
count = count-1;
print ("Incorrect Password...Tries Remaining", count);
else:
print("Password accepted, security system offline");
#BRANCHING CODE GOES HERE
break
if count == 0:
print("Contacting Owner!");
#BRANCHING CODE GOES HERE
except:
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
答案 40 :(得分:0)
接受的答案甚至where city regexp '(boro|town)$' and
average_house_value <= 250000;
的版本都不适合我,因此我编写了以下版本:
Boost
这将从字符串中的任何位置删除所有空格字符,并返回该字符串的新副本。
答案 41 :(得分:0)
我已经阅读了大多数答案,但是没有发现有人在使用istringstream
std::string text = "Let me split this into words";
std::istringstream iss(text);
std::vector<std::string> results((std::istream_iterator<std::string>(iss)),
std::istream_iterator<std::string>());
结果是单词的向量,它也可以处理具有内部空格的字符串,希望对您有所帮助。
答案 42 :(得分:0)
为什么不使用lambda?
auto no_space = [](char ch) -> bool {
return !std::isspace<char>(ch, std::locale::classic());
};
auto ltrim = [](std::string& s) -> std::string& {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), no_space));
return s;
};
auto rtrim = [](std::string& s) -> std::string& {
s.erase(std::find_if(s.rbegin(), s.rend(), no_space).base(), s.end());
return s;
};
auto trim_copy = [](std::string s) -> std::string& { return ltrim(rtrim(s)); };
auto trim = [](std::string& s) -> std::string& { return ltrim(rtrim(s)); };
答案 43 :(得分:0)
修剪两端。
string trim(const std::string &str){
string result = "";
size_t endIndex = str.size();
while (endIndex > 0 && isblank(str[endIndex-1]))
endIndex -= 1;
for (size_t i=0; i<endIndex ; i+=1){
char ch = str[i];
if (!isblank(ch) || result.size()>0)
result += ch;
}
return result;
}
答案 44 :(得分:0)
我正在使用这个:
void trim(string &str){
int i=0;
//left trim
while (isspace(str[i])!=0)
i++;
str = str.substr(i,str.length()-i);
//right trim
i=str.length()-1;
while (isspace(str[i])!=0)
i--;
str = str.substr(0,i+1);
}
答案 45 :(得分:-1)
看来我参加派对的时间已经很晚了 - 我简直不敢相信7年前这个问题!
这是我对这个问题的看法。我正在研究一个项目,我现在不想经历使用Boost的麻烦。
std::string trim(std::string str) {
if(str.length() == 0) return str;
int beg = 0, end = str.length() - 1;
while (str[beg] == ' ') {
beg++;
}
while (str[end] == ' ') {
end--;
}
return str.substr(beg, end - beg + 1);
}
此解决方案将从左侧和右侧进行修剪。
答案 46 :(得分:-2)
我很烦
对于我,这是解决问题的最快方法:
CString tmp(line.c_str());
tmp = tmp.Trim().MakeLower();
string buffer = tmp;
好的,我可以使用lambda ops,迭代器和所有其他东西,这很酷。但是我只需要处理一个字符串而不是一个字符...