我正在尝试用c ++语言实现Ceaser密码
#include <iostream>
#include <string>
#include <locale>
using namespace std;
int main()
{
string word;
getline(cin,word);
for(int i=0; i<word.length();i++)
{
if(isalnum(word[i]))
{
//shift by 3
word[i]+= 3;
}
}
cout << word ;
return 0;
}
我想要的是仅限于字母和数字的输出。 例如,如果我想将z移位3,那么输出将是'c'而不是我的代码中的'}'。
答案 0 :(得分:1)
编译器在处理繁琐的细节方面要比人类好得多,因此在这种情况下,我会编写代码以清楚地显示您的意图,然后让编译器弄清楚数字。
例如,如果你想转换一个字母,不要真的只想在A到Z范围内的字母索引中加3,然后用26修改 - 字母数从A到Z?这就是你想要的 - 围绕A到Z的字母圈旋转,其中有26个,不用担心ASCII值。
在这种情况下,您可以让编译器为您解决:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int shift = 3;
char* input = "Is it 90 with a ZERO?";
printf("%s\n", input);
int length = strlen(input);
char* output = malloc(length + 1);
output[length] = '\0';
for (int i = 0; i < length; i++)
{
char c = input[i];
if (c >= 'A' && c <= 'Z')
{
c = (((c - 'A') + shift) % 26) + 'A';
}
else if (c >= 'a' && c <= 'z')
{
c = (((c - 'a') + shift) % 26) + 'a';
}
else if (c >= '0' && c <= '9')
{
c = (((c - '0') + shift) % 10) + '0';
}
output[i] = c;
}
printf("%s\n", output);
}
如果你不担心速度或内存占用,你为什么要承担这个责任?
答案 1 :(得分:0)
这应该有效。这假设只有小写字母。
word[i]+= 3;
//at this point word[i] might have cross the ascii limit for lower case letters
ie可能是word[i]>122
。小写字母的Ascii范围是97-122
所以我们使用mod
来包装它。
但现在可能会word[i]<97
再次超出范围,因此我们会向其添加97
。
word[i]%=123;
if(word[i]<97)word[i]+=97;
示例z
word[i]+=3 makes word[i] as 125 //out of range
word[i]%=123 //word[i]=3
word[i]+=97 //word[i]=99=c
答案 2 :(得分:0)
您必须确保它不会超出ASCII字母的有效范围。这样做的一种方法是将输入转换为小写,然后确保在添加班次时,它不会超过122
(z
的ASCII值。
if (word[i] + SHIFT > 'z') {
SHIFT -= 123 - word[i];
word[i] = 'a'; // go back to the beginning
word[i] += SHIFT; // add on the remaining amount
}