填坑日记:关于std::string::npos的坑
- 再创世纪·代码厨房
- 2020-02-07
- 559热度
- 1评论
今天新开一个文章分类,名唤“填坑日记”。用于记录日常碰到的小坑,不注文序,不分语言。以前踩过的坑,如果哪天突然想起来,就补充进来。
坑的描述 | 使用std::string::npos出现出乎意料的情况 |
---|---|
根本原因 | 无符号数赋负值 |
填坑进度 | 已解决 |
问题描述:
今天的坑由一段简单的代码引起。这段代码用于实现在字符串中查找指定串,替换成另一个指定串。
[cpp]
int iPos = std::string::npos;
while ((iPos = strResult.find(strReplaceFrom)) > std::string::npos)
{
strResult.replace(iPos, strReplaceFrom.length(), strReplaceTo);
}
[/cpp]
其中std::string::npos的定义如下(http://www.cplusplus.com/reference/string/string/npos/):
[cpp]
static const size_t npos = -1;
[/cpp]
明明find到了(iPos > -1),却进入不了循环体。费解不?
原因分析:
其实原因很简单。size_t是unsigned int的typedef,这个坑实际上是无符号数赋负值的老问题。对无符号数赋值-1,内存中表示为全1,即相当于赋unsigned int最大值。以下一段代码可以说明这个问题:
[cpp]
int i = INT_MAX;
unsigned int u = -1;
if(i > u)
{
printf("i is Larger than u");
}
else
{
printf("i is NOT Larger than u");
}
[/cpp]
注意下图中两个变量的值。
解决方案:
[cpp]
int iPos = std::string::npos;
while ((iPos = strResult.find(strReplaceFrom)) > (int)std::string::npos)
{
strResult.replace(iPos, strReplaceFrom.length(), strReplaceTo);
}
[/cpp]
或者直接将std::string::npos替换成-1。
二零二零年二月七日
顾毅写于厦门
不错,继续往技术大牛方向积累。多多发文章。。。