C++ 检查 std::string 是否只有空格的有效方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6444842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Efficient way to check if std::string has only spaces
提问by karlphillip
I was just talking with a friend about what would be the most efficient way to check if a std::string has only spaces. He needs to do this on an embedded project he is working on and apparently this kind of optimization matters to him.
我只是和一个朋友谈论检查 std::string 是否只有空格的最有效方法。他需要在他正在从事的嵌入式项目上执行此操作,显然这种优化对他很重要。
I've came up with the following code, it uses strtok()
.
我想出了以下代码,它使用strtok()
.
bool has_only_spaces(std::string& str)
{
char* token = strtok(const_cast<char*>(str.c_str()), " ");
while (token != NULL)
{
if (*token != ' ')
{
return true;
}
}
return false;
}
I'm looking for feedback on this code and more efficient ways to perform this task are also welcome.
我正在寻找有关此代码的反馈,也欢迎使用更有效的方法来执行此任务。
回答by Mark B
if(str.find_first_not_of(' ') != std::string::npos)
{
// There's a non-space.
}
回答by Michael Goldshteyn
In C++11, the all_of
algorithm can be employed:
在 C++11 中,all_of
可以使用该算法:
// Check if s consists only of whitespaces
bool whiteSpacesOnly = std::all_of(s.begin(),s.end(),isspace);
回答by David Hammen
Why so much work, so much typing?
为什么要做这么多工作,打这么多字?
bool has_only_spaces(const std::string& str) {
return str.find_first_not_of (' ') == str.npos;
}
回答by Tom
Wouldn't it be easier to do:
这样做不是更容易吗:
bool has_only_spaces(const std::string &str)
{
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
{
if (*it != ' ') return false;
}
return true;
}
This has the advantage of returning early as soon as a non-space character is found, so it will be marginally more efficient than solutions that examine the whole string.
这具有在发现非空格字符后立即返回的优点,因此它比检查整个字符串的解决方案效率略高。
回答by ericcurtin
To check if string has only whitespace in c++11:
要检查字符串在 c++11 中是否只有空格:
bool is_whitespace(const std::string& s) {
return std::all_of(s.begin(), s.end(), isspace);
}
in pre-c++11:
在 C++11 之前:
bool is_whitespace(const std::string& s) {
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
if (!isspace(*it)) {
return false;
}
}
return true;
}
回答by GameSalutes
Here's one that only uses STL (Requires C++11)
这是一个只使用 STL(需要 C++11)
inline bool isBlank(const std::string& s)
{
return std::all_of(s.cbegin(),s.cend(),[](char c) { return std::isspace(c); });
}
It relies on fact that if string is empty (begin = end) std::all_of also returns true
它依赖于如果字符串为空(开始 = 结束)std::all_of 也返回 true 的事实
Here is a small test program: http://cpp.sh/2tx6
下面是一个小测试程序:http: //cpp.sh/2tx6
回答by J?rgen Sigvardsson
Using strtok like that is bad style! strtok modifiesthe buffer it tokenizes (it replaces the delimiter chars with \0).
像这样使用 strtok 是糟糕的风格!strtok修改它标记化的缓冲区(它用 \0 替换分隔符字符)。
Here's a non modifying version.
这是一个非修改版本。
const char* p = str.c_str();
while(*p == ' ') ++p;
return *p != 0;
It can be optimized even further, if you iterate through it in machine word chunks. To be portable, you would also have to take alignment into consideration.
如果您在机器词块中迭代它,它可以进一步优化。为了便于携带,您还必须考虑对齐。
回答by CashCow
I do not approve of you const_casting above and using strtok.
我不赞成你在上面使用 const_casting 和使用 strtok。
A std::string can contain embedded nulls but let's assume it will be all ASCII 32 characters before you hit the NULL terminator.
std::string 可以包含嵌入的空值,但让我们假设在您遇到空值终止符之前它将是所有 ASCII 32 字符。
One way you can approach this is with a simple loop, and I will assume const char *.
解决这个问题的一种方法是使用一个简单的循环,我将假设 const char *。
bool all_spaces( const char * v )
{
for ( ; *v; ++v )
{
if( *v != ' ' )
return false;
}
return true;
}
For larger strings, you can check word-at-a-time until you reach the last word, and then assume the 32-bit word (say) will be 0x20202020 which may be faster.
对于较大的字符串,您可以一次检查一个单词,直到到达最后一个单词,然后假设 32 位单词(比如说)将是 0x20202020,这可能会更快。
回答by James Kanze
Something like:
就像是:
return std::find_if(
str.begin(), str.end(),
std::bind2nd( std::not_equal_to<char>(), ' ' ) )
== str.end();
If you're interested in white space, and not just the space character, then the best thing to do is to define a predicate, and use it:
如果您对空格感兴趣,而不仅仅是空格字符,那么最好的做法是定义一个谓词并使用它:
struct IsNotSpace
{
bool operator()( char ch ) const
{
return ! ::is_space( static_cast<unsigned char>( ch ) );
}
};
If you're doing any text processing at all, a collection of such simple
predicates will be invaluable (and they're easy to generate
automatically from the list of functions in <ctype.h>
).
如果您要进行任何文本处理,那么这些简单谓词的集合将是无价之宝(而且它们很容易从 中的函数列表中自动生成<ctype.h>
)。
回答by Nim
it's highly unlikely you'll beat a compiler optimized naive algorithm for this, e.g.
您不太可能为此击败编译器优化的幼稚算法,例如
string::iterator it(str.begin()), end(str.end())
for(; it != end && *it == ' '; ++it);
return it == end;
EDIT: Actually - there is a quicker way (depending on size of string and memory available)..
编辑:实际上 - 有一种更快的方法(取决于字符串和可用内存的大小)。
std::string ns(str.size(), ' ');
return ns == str;
EDIT: actually above is not quick.. it's daft... stick with the naive implementation, the optimizer will be all over that...
编辑:实际上上面并不快......它很愚蠢......坚持天真的实现,优化器将全部结束......
EDIT AGAIN: dammit, I guess it's better to look at the functions in std::string
再次编辑:该死的,我想最好看看中的函数std::string
return str.find_first_not_of(' ') == string::npos;