如何检查字符串是否包含空格/制表符/新行(任何空白的行)?

时间:2012-07-11 02:02:43

标签: c++

我知道有一个“isspace”函数可以检查空格,但这需要我遍历字符串中的每个字符,这可能会影响性能,因为这会被称为很多。有没有快速的方法来检查std :: string是否只包含空格?

前:

function("       ") // returns true
function("    4  ") // returns false

我想到的一个解决方案是使用正则表达式,然后我会知道它只包含空格,如果它是假的......但我不确定这是否比isspace函数更有效。

regex: [\w\W] //checks for any word character(a,b,c..) and non-word character([,],..)

提前感谢!

5 个答案:

答案 0 :(得分:8)

使用常规字符串,您可以做的最好的形式是:

return string::find_first_not_of("\t\n ") == string::npos;

在最坏的情况下,这将是O(n),但在不知道其他字符串的情况下,这将是您能做的最好的事情。

答案 1 :(得分:7)

任何方法都需要查看字符串的每个字符。在每个字符上调用isspace()的循环非常有效。如果编译器内联isspace(),那么这将是最接近最佳的。

当然,一旦看到非空格字符,循环就应该中止。

答案 2 :(得分:2)

你正在假设正则表达式不会遍历字符串。正则表达式可能比线性搜索重得多,因为它可能会构建一个FSM并基于此进行遍历。

你可以进一步加速并使其成为近乎恒定的时间操作的唯一方法是通过迭代对字符串的每次更新来缓存成本并缓存一个bool /位来跟踪是否有类似空格的字符,如果之后没有进行任何更改,则返回该值,并在对该字符串执行写操作时更新该位。但是,这会牺牲/减慢修改操作的速度,从而提高自定义has_space()的速度。

答案 3 :(得分:1)

对于它的价值,一个语言环境有一个函数(scan_is)来做这样的事情:

#include <locale>
#include <iostream>
#include <iomanip>

int main() {

    std::string inputs[] = { 
        "all lower",
        "including a space"
    };

    std::locale loc(std::locale::classic());

    std::ctype_base::mask m = std::ctype_base::space;

    for (int i=0; i<2; i++) {
        char const *pos;
        char const *b = &*inputs[i].begin();
        char const *e = &*inputs[i].end();

        std::cout << "Input: " << std::setw(20) << inputs[i] << ":\t";
        if ((pos=std::use_facet<std::ctype<char> >(loc).scan_is(m, b, e)) == e)
            std::cout << "No space character\n";
        else
            std::cout << "First space character at position " << pos - b << "\n";
    }
    return 0;
}

对于(很多)问题,是否在循环中使用isspace(或使用std::find_if)提供了很多(如果有的话)真正的优势,这可能是开放的。

答案 4 :(得分:0)

如果所有字符都在给定列表中,您也可以使用find_first_not_of。 然后你可以避免循环。

这是一个例子

#include <string>
#include <algorithm>
using namespace std;
int main()
{
    string str1="      ";
    string str2="      u    ";
    bool ContainsNotBlank1=(str1.find_first_not_of("\t\n ")==string::npos);
    bool ContainsNotBlank2=(str2.find_first_not_of("\t\n ")==string::npos);
    bool ContainsNotBlank3=(str2.find_first_not_of("\t\n u")==string::npos);
    cout << ContainsNotBlank1 <<endl;
    cout << ContainsNotBlank2 <<endl;
    cout << ContainsNotBlank3 <<endl;
    return 0;
}

输出: 1:因为只有空白和一个标签 0:因为你没有进入“\ t \ n”列表 1:因为str2包含空格,制表符和u。

希望它有所帮助 如果您有任何问题,请告诉我