string.find() 在使用 ==-1 时返回 true,但在使用 <0 时返回 false

string.find() returns true when ==-1 is used but false when <0 is used

本文关键字:返回 false true string find      更新时间:2023-10-16

我试图在字符串中查找字符,但得到意想不到的结果。我的理解是,string::find(char c)在找不到时返回-1。但是,我得到了一些意想不到的结果。

即使字符串不包含'8',它仍然返回true

std::string s = "123456799";
if(s.find('8')<0)
    cout << "Not Found" << endl;
else
    cout <<  "Found" << endl;
//Output: Found

但是,当使用==时,代码会按预期工作。

std::string s = "123456799";
if(s.find('8')==-1)
    cout << "Not Found" << endl;
else
    cout <<  "Found" << endl;
//Output: Not Found

我的理解是,string::find(char c)在找不到时返回-1

这是不准确的。根据文档:

返回值
找到的子字符串或 npos 的第一个字符的位置(如果没有( 找到这样的子字符串。

所以准确地说,当找不到时std::string::find将返回 std::string::npos。关键是std::string::npos的类型是 std::string::size_type ,这是一个无符号整数类型。即使它是从 -1 的值初始化的,它也不是-1;它仍然没有签名。所以s.find('8')<0永远是false的,因为不可能是消极的。

标准文档::字符串::

npos:

static const size_type npos = -1;

这是一个特殊值,等于类型 size_type 表示的最大值。

所以你应该使用 std::string::npos 来检查结果,以避免这种混淆。

if (s.find('8') == std::string::npos)
    cout << "Not Found" << endl;
else
    cout <<  "Found" << endl;

if(s.find('8')==-1)工作正常,因为这里的运算符 == 的左操作数是无符号的,右手的操作数是有符号的。根据算术运算符的规则,

    否则,如果无符号操作数的转换等级大于或等于有符号操作数
  • 的转换等级,则有符号操作数将转换为无符号操作数的类型。

因此,-1将转换为 unsigned,这是 std::string::npos 的值,然后所有工作都按预期工作。

string::find()返回size_t,这是一个无符号的int,所以它永远不会是负数。