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

4

我正在尝试在字符串中查找一个字符,但结果出乎意料。据我所知,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

请阅读文档(http://en.cppreference.com/w/cpp/string/basic_string/find)。在哪里可以找到`std::string_find`返回`-1`的信息? - PaulMcKenzie
1
@PaulMcKenzie 如果未找到,std::string_find将返回string::npos,string::npos是“static const size_t npos = -1;”。 - user3196144
1
@user3196144 注意 npos 的类型是无符号的;它被初始化为 -1 并不意味着它是负数。请注意这里的解释(http://en.cppreference.com/w/cpp/string/basic_string/npos),“这是一个特殊值,等于类型 size_type 可表示的最大值。” - songyuanyao
@user3196144 注意,原帖的提问者遵循了您的建议,现在必须在SO上询问为什么他们的程序无法工作。始终阅读文档。如果函数返回一个值,并且该值被命名为npos,请返回npos - PaulMcKenzie
2个回答

8
我的理解是,当未找到时,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,因为不可能是负数。

std::string::npos的文档:

static const size_type npos = -1;

This is a special value equal to the maximum value representable by the type 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) 很好地工作了,因为这里operator==的左操作数是无符号的,右操作数是有符号的。根据算术运算符的规则,

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

所以-1将被转换为无符号数,即std::string::npos的值,然后一切都按预期工作。


1

string::find() 返回 size_t,它是一个无符号整数,因此它永远不可能为负数。


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