#include <stdio.h>
#include <string.h>
int main()
{
int key;
char line[500];
char ch = '\0';
int i = 0;
printf("Enter key: ");
scanf("%d", &key);
getchar();
printf("Enter line: ");
while(ch != '\n')
{
ch = getchar();
line[i] = ch;
i++;
}
int length = i;
int k = 0;
char temp[length];
for(i = 0; i < length; i++)
{
if((int)line[i] >= 65 && (int)line[i] <= 90)
{
temp[k++] = (int)line[i] + key;
} else if((int)line[i] >= 97 && (int)line[i] <= 122){
temp[k++] = (int)line[i] + key;
} else {
temp[k++] = line[i];
}
}
printf("\n");
for(i = 0; i < length; i++)
{
printf("%c", temp[i]);
}
}
到目前为止,我所做的是将字符转换为另一个字符。例如,如果我输入&#34; abc ABC&#34;并且添加值(int键)是3,那么它应该打印出&#34; def DEF&#34;。
这样可以正常工作,但我想要进一步实现的是在角色出界时回放角色。例如,如果我输入&#34; XYZ&#34;并且添加值为3,它应打印出&#34; ABC&#34;,而不是&#34; []&#34;。我可以请求任何帮助或建议如何解决这个问题?感谢..
答案 0 :(得分:1)
首先,当我看到
if((int)line[i] >= 65 && (int)line[i] <= 90)
我的第一反应是,“65和90是什么意思?”嗯,我知道,但是,这些数字对你来说是一个不必要的麻烦,并且它们对读者来说是一个不必要的麻烦。所以只说
if(line[i] >= 'A' && line[i] <= 'Z')
代替。在C中,像'A'
这样的字符常量的值是机器字符集中字符的值,或ASCII中的65。 (我也摆脱了一些不必要的演员阵容。)
接下来,一种解决问题的蛮力方法就是检查溢出:
if(line[i] >= 'A' && line[i] <= 'Z')
{
temp[k] = line[i] + key;
if(temp[k] > 'Z')
temp[k] -= 26;
k++;
}
由于在完成之前我必须使用temp[k]
做几件事,所以我将k++
移到了最后。
你会对a-z案使用类似的代码。
如果您想使程序更加通用,那么key
也可能是否定的。在这种情况下,你也要担心字母“小于”A。您可以像这样扩展代码:
if(line[i] >= 'A' && line[i] <= 'Z')
{
temp[k] = line[i] + key;
if(temp[k] > 'Z')
temp[k] -= 26;
else if(temp[k] < 'A')
temp[k] += 26;
k++;
}
同样,你会为a-z案例重复这一点。
现在,这种非暴力的方式是认识到我们在这里做的“环绕式”算术也就是所谓的“模数”算术,因为它与“模数”或“余数”有关。运算符%
。因此,如果您了解%
的工作原理,您可以编写如下代码:
if(line[i] >= 'A' && line[i] <= 'Z')
{
int c = line[i] - 'A';
c = (c + key) % 26;
temp[k++] = c + 'A';
}
它仍然不是非常简单,因为我们必须从像'Y'这样的字母到字母表中的0位置(25),到它的移位值(28,假设key
为3),到它的“模数”值{2},然后最后回到像'B'这样的字母。
或者,更详细地说,正在发生的是大写字母是ASCII,65到90.所以我们减去65得到0-25范围内的数字。一旦我们在0-25范围内,我们就可以使用模数运算,因为% 26
基本上意味着“只有0到25范围内的整数”。最后,当我们完成模数运算时,我们再次添加65,以回到65-90范围的实际字母。 (而不是减去和添加65,我们减去并添加'A'
,因为它是相同的值,但更清晰。)
而且,我仍然只显示大写字母的代码;你也必须为a-z案例重复这段代码。