C++ 加密字符串但接收无限循环 问题:
我试图用一条规则加密C++ 加密字符串但接收无限循环 问题:,c++,C++,我试图用一条规则加密std::string密码: 在元音前后加上“0” 使bAnanASplit变成b0A0n0a0n0A0Spl0i0t。 然而,我陷入了一个无限循环 代码如下: const std::string元音=“AEIOUaeiou”; std::string pass=“bAnanASplit”; //在元音前后加零 对于(int i=0;i
std::string
密码:
- 在元音前后加上“0”
bAnanASplit
变成b0A0n0a0n0A0Spl0i0t
。
然而,我陷入了一个无限循环
代码如下:
const std::string元音=“AEIOUaeiou”;
std::string pass=“bAnanASplit”;
//在元音前后加零
对于(int i=0;i std::cout永远不要修改您正在迭代的集合/容器!
这样可以省去你很多麻烦
让我们从代码开始,生成一个新字符串,其中元音由0
包围
const std::string VOWELS = "AEIOUaeiou";
std::string pass = "bAnanASplit", replacement;
//Add zeroes before and after vowels
for (auto ch : pass)
{
if(VOWELS.find(ch) != std::string::npos)
replacement += '0' + ch + '0';
else
replacement += ch;
}
如果i
变成std::string::npos
,你就不会退出循环。因此,i
值在到达i之后的最后一个i或0的位置时(这里我指的是split)会被更改为一些意外值(可能类似-1)。这是因为i
是一个有符号整数,但在这种情况下find_first_of()
返回std::string::npos
,这是size\u t
可以保持的最大值。在这种情况下,终止条件i
可能成立,循环继续。因此,我建议您对代码进行以下更改-
for (size_t i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
if(i == std::string::npos)
break;
pass.insert(pass.begin() + i++, '0');
pass.insert(pass.begin() + ++i, '0');
}
for(size_t i=0;i
同样,如果(i!=std::String::npos)
没有达到您期望的效果,那么
但是再次强调,当您在容器上进行迭代时,最好不要修改容器,@Tanveer在他的回答中提到了这一点,因为OP似乎在寻找错误行为的确切原因,我想添加另一个答案,因为现有的答案没有显示确切的问题
意外行为的原因在以下几行中可见
for (int i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
...
“从来没有……”通常是错误的。事实上,您可以在迭代时修改容器,只要您保证在每次迭代结束时正确更新使用的迭代器。当然,您是对的,而且您的方式更好,但另一个答案回答了实际问题。您仍然可以添加该部分,以便整个答案位于1位。+1!“…当i值到达最后一个i的位置时,它不会改变”为什么?你能澄清一下这一点吗?@Jaidepshekhar,很抱歉它确实发生了变化,变成了std::string::npos。但是npos是无符号值,你把它存储为一个整数,所以它变成了-1,它从字符串的开头开始。这个答案回答了我的问题,另一个告诉我们更好的解决方法。啊,你们面临的困境是e positioning…:-)@jaidepshekhar,如果Tanveer的答案对你有效,那么选择它作为答案。我只希望我的答案能够指出你代码中的错误。:)当进行大量计算时,一个有趣的补充是…是的,我认为直接字符串连接将比使用stringstream
作为生成的字符串更好g不会很长。但是,除非您多次重复此操作,否则不会注意到显著的性能差异(在这种情况下,在这里讨论的三种方法中的任何一种)。
for (int i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
...
#include <iostream>
#include <sstream>
int main() {
using namespace std;
const string VOWELS = "AEIOUaeiou";
const string pass = "bAnanASplit";
stringstream ss;
for (const char pas : pass) {
if (VOWELS.find(pas) == std::string::npos) {
ss << pas;
} else {
ss << '0' << pas << '0';
}
}
cout << pass << "\n";
cout << ss.str() << endl;
}