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;istd::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;
}