我目前正在使用以下代码在我的程序中右修剪所有std::字符串:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
我目前正在使用以下代码在我的程序中右修剪所有std::字符串:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
当前回答
我认为在这个例子中使用宏是一个很好的实践:(适用于c++ 98)
#define TRIM_CHARACTERS " \t\n\r\f\v"
#define TRIM_STRING(given) \
given.erase(given.find_last_not_of(TRIM_CHARACTERS) + 1); \
given.erase(0, given.find_first_not_of(TRIM_CHARACTERS));
例子:
#include <iostream>
#include <string>
#define TRIM_CHARACTERS " \t\n\r\f\v"
#define TRIM_STRING(given) \
given.erase(given.find_last_not_of(TRIM_CHARACTERS) + 1); \
given.erase(0, given.find_first_not_of(TRIM_CHARACTERS));
int main(void) {
std::string text(" hello world!! \t \r");
TRIM_STRING(text);
std::cout << text; // "hello world!!"
}
其他回答
在空字符串的情况下,你的代码假设将1添加到string::npos得到0。String::npos的类型是String::size_type,无符号。因此,您依赖于加法的溢出行为。
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 );
}
使用Boost的字符串算法是最简单的:
#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,你可以修剪所有满足自定义谓词的字符,而不是只有空白。
我认为在这个例子中使用宏是一个很好的实践:(适用于c++ 98)
#define TRIM_CHARACTERS " \t\n\r\f\v"
#define TRIM_STRING(given) \
given.erase(given.find_last_not_of(TRIM_CHARACTERS) + 1); \
given.erase(0, given.find_first_not_of(TRIM_CHARACTERS));
例子:
#include <iostream>
#include <string>
#define TRIM_CHARACTERS " \t\n\r\f\v"
#define TRIM_STRING(given) \
given.erase(given.find_last_not_of(TRIM_CHARACTERS) + 1); \
given.erase(0, given.find_first_not_of(TRIM_CHARACTERS));
int main(void) {
std::string text(" hello world!! \t \r");
TRIM_STRING(text);
std::cout << text; // "hello world!!"
}
我已经阅读了大部分答案,但没有发现任何人使用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>());
结果是单词的向量,它可以处理有内部空白的字符串,希望这有帮助。