问题:
我试图用一条规则加密std::string
密码:
在元音之前和之后添加“ 0”
使bAnanASplit
变为b0A0n0a0n0A0Spl0i0t
。
但是,我陷入了无限循环。
这是代码:
const std::string VOWELS = "AEIOUaeiou";
std::string pass = "bAnanASplit";
//Add zeroes before and after vowels
for (int i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
std::cout << pass << "\n";
if(i != std::string::npos)
{
std::cout << pass[i] << ": " << i << "\n";
pass.insert(pass.begin() + i++, '0');
pass.insert(pass.begin() + ++i, '0');
}
}
...结果:
bAnanASplit
A: 1
b0A0nanASplit
a: 5
b0A0n0a0nASplit
A: 9
b0A0n0a0n0A0Split
i: 15
b0A0n0a0n0A0Spl0i0t
b0A0n0a0n0A0Spl0i0t
A: 2
b00A00n0a0n0A0Spl0i0t
a: 8
b00A00n00a00n0A0Spl0i0t
A: 14
b00A00n00a00n00A00Spl0i0t
i: 22
b00A00n00a00n00A00Spl00i00t
b00A00n00a00n00A00Spl00i00t
...
有什么帮助吗?这肯定看起来很奇怪。
编辑:所有答案都是有用的,因此我接受了我认为最能回答该问题的答案。但是,this答案中显示了解决问题的最佳方法。
最佳答案
由于OP似乎正在寻找行为不当的确切原因,因此我想添加另一个答案,因为现有的答案并未显示确切的问题。
出现意外行为的原因在以下几行中可见。
for (int i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
...
问题一:
循环计数器
i
是int
(即signed int
)。但是如果没有匹配项,std::string::find_first_of将返回std::string::npos。这通常是unsigned long
可表示的最大数目。将一个较大的unsigned
值分配给一个较短的signed
变量将存储一个完全意外的值(假设您不知道该值)。在这种情况下,i
在大多数平台上都将变为-1
(如果需要确定,请尝试int k = std::string::npos;
并打印k
)。 i = -1
是循环条件i < pass.length()
的有效状态,因此将允许下一次迭代。问题2:
与上述问题密切相关,相同的变量
i
用于定义find
操作的开始位置。但是,如前所述,i
不会像您期望的那样代表字符的索引。解:
可以使用适当的数据类型来解决存储格式错误的值的问题。在当前情况下,最好的选择是使用
std::string::size_type
,因为它总是可以保证工作(很可能在任何地方都等于size_t
)。为了使程序与给定的逻辑一起工作,您还必须使用其他变量来存储find
结果。但是,更好的解决方案是使用
std::stringstream
生成字符串。这比通过在中间插入字符来修改字符串更好。例如
#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;
}
关于c++ - 加密字符串但收到无限循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59235917/