C++如何检查字符串是否为空或空格

6
基本上,我有一串空格" "或者一些行中有空白块或""空的文件,并且我想知道C++中是否有检查这个的函数。
*注意:*作为一个附加问题,在C++中如果我想要分解一个字符串并检查它是否符合某种模式,我应该使用哪个库?如果我想自己编码,我应该知道哪些基本函数来操作字符串?有没有好的参考资料?

目前发布的许多答案似乎都缺少“或空格块”的子句。我认为这个想法是找到只包含零个或多个空格的行,其中“或多个”可以超过1个。 - SCFrench
@SC:问题的那部分是大多数答案之后添加的(在我看来是不必要的)澄清。 "字符串"已经是一个字符序列,不仅限于一个字符。但是,嘿,我试图提供一个解决方案,考虑到这一点,并因为假设输入是ASCII而被Alf抨击(在我看来,这是一个更合理的假设)。所以我的答案将永远落后。没关系,我不需要声望。我把它留在那里,以防Mark欣赏实际有效的答案。 - Ben Voigt
@Ben:抱歉,我并没有试图“猛烈批评”你。只是许多新手编写的isspace和其它函数的简单调用都是错误的。因此,我认为纠正这些简单的调用非常重要,以便读者可以学习如何正确地调用这些函数(以及不直接调用它们的危险)。 - Cheers and hth. - Alf
@Alf:我立刻意识到你关于传递负值和相关问题的潜在性是正确的。大多数新手可能会受益于被告知isspace在扩展字符上的工作方式并不像他们期望的那样可靠。 - Ben Voigt
6个回答

6
bool isWhitespace(std::string s){
    for(int index = 0; index < s.length(); index++){
        if(!std::isspace(s[index]))
            return false;
    }
    return true;
}

使用std::isspace(static_cast<unsigned char>(s[index])) - cppreference.com - starriet

3
std::string str = ...;
if (str.empty() || str == " ") {
    // It's empty or a single space.
}

不考虑多个空格。 - Paul Hazen

2
 std::string mystr = "hello";

 if(mystr == " " || mystr == "")
   //do something

在分解字符串时,std::stringstream很有帮助。

2
您的一些文件行中没有“nullstring”。
但是您可以有一个空字符串,也就是空行。
您可以使用例如std::string.length或者如果您更喜欢C语言,strlen函数。
为了检查空格,isspace函数很方便,但请注意对于char字符,参数应该转换为unsigned char,例如:
bool isSpace( char c )
{
    typedef unsigned char UChar;
    return bool( ::isspace( UChar( c ) ) );
}

干杯并祝一切顺利。

这根本不处理字符串,更不用说“空格(字符)串”具有任意长度(空格是不可数的)。而且盲目地将非ASCII字符串强制转换为unsigned char通常是错误的做法。 - Ben Voigt
@Ben:如果你的论点正确,它将适用于大多数C++标准库的字符处理......:-( 处理UTF-8和其他可变长度编码要困难得多,因为标准库有一个固定大小的假设。上面的函数是最有效和最通用的函数。因此,可以使用任何您想要的条件包装该函数,但会付出效率成本。另一方面,从有限的函数生成高效且最通用的函数通常是不可能的。实质上,在底层添加低效性后,无法摆脱低效性。 - Cheers and hth. - Alf
@Ben:抱歉,我不相信你自己都相信这一点。你必须知道使用C++制作的无数应用程序。嘿。 - Cheers and hth. - Alf
@Ben:告诉微软去吧。 :-) - Cheers and hth. - Alf
今天关于这个话题我收到了一个无法解释的负评,这可能是有策略性的投票,或者是有人认为他们知道一些我们不知道的事情,但又不愿意分享。 - Ben Voigt
显示剩余5条评论

0

由于您没有指定字符> 0x7f 的解释,我假设它是ASCII编码(即字符串中没有高位字符)。

#include <string>
#include <cctype>

// Returns false if the string contains any non-whitespace characters
// Returns false if the string contains any non-ASCII characters
bool is_only_ascii_whitespace( const std::string& str )
{
    auto it = str.begin();
    do {
        if (it == str.end()) return true;
    } while (*it >= 0 && *it <= 0x7f && std::isspace(*(it++)));
             // one of these conditions will be optimized away by the compiler,
             // which one depends on whether char is signed or not
    return false;
}

-1 通常是错误的调用 std::isspace。参数需要转换为 unsigned char(或等效表达式)。请修复。 - Cheers and hth. - Alf
@Alf:强制转换为“unsigned char”也不正确。当您开始支持非ASCII字符时,您需要知道编码,开始考虑多字节字符等问题。 - Ben Voigt
@Ben:isspace并不是硬编码的。它的效果取决于C库的语言环境,这个语言环境可以通过setlocale来选择。因此,在程序开始时调用setlocale(LC_ALL, "")通常是一个好主意。这将把语言环境从C语言环境(纯ASCII)更改为机器上自然用户的语言环境,例如Windows ANSI。也许我应该提到这一点。我忘了,所以感谢你深入探究这个问题。 - Cheers and hth. - Alf
@Alf:在这个过程中,额外的区域处理变得比非负性检查更加昂贵(如果我真的关心性能,我会将上下界限制在ASCII空白字符集合上,并在一个小表中进行查找)。然后,在<locale>中还有isspace的重载版本,以控制方式处理扩展字符。 - Ben Voigt
@Ben:我没有谈论任何“额外”的区域设置处理。只是isspace并没有像你想的那样硬编码,而且初始调用setlocale是一个好主意,以便能够使用这些C库函数。你提出的性能改进想法,据我所知,是典型的isspace实现方式。PS:Latin-1是Windows ANSI Western的严格子集,我不认为后者添加了任何空白字符。虽然如此,这与我们的讨论无关,除非你在示例中无意中(很可能是错误地)使用了这两个字符。干杯! - Cheers and hth. - Alf
显示剩余7条评论

-2
如果你想进行模式检查,请使用正则表达式。

这对于像这样简单的场景来说完全过度了。此答案也缺乏任何细节。 - Lightness Races in Orbit
他问道:“如果我想将一个字符串分解并检查其模式,我应该使用哪个库?” - Daniel
作为一个“附带问题”,Stack Overflow不支持“附带问题”。而且,“regexp”不是一个库,它是一个广泛描述各种正则表达式引擎的术语,由各种库实现。 - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接