我正在尝试用C创建一个简单的Caesar shift程序,但我似乎无法弄明白。该程序不断崩溃。任何帮助将不胜感激。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int arc, const char* argv[])
{
int shift = atoi(argv[1]);
char message[256];
strcpy(message, argv[2]);
int i;
for(i = 0; i < strlen(message); i++) {
printf("%c", message[i] + shift);
}
putchar('\n');
return 0;
}
答案 0 :(得分:5)
你没有正确实施凯撒密码。您的代码包含以下行,这是错误的:
printf("%c", message[i] + shift);
要正确执行此操作,您需要将其转换为函数:
printf("%c", encrypt(message[i], shift));
让我们实现这个功能:
char encrypt(char input, int shift) {
if (input >= 'a' && input <= 'z')
return ((input - 'a' + shift) % 26) + 'a';
if (input >= 'A' && input <= 'Z')
return ((input - 'A' + shift) % 26) + 'A';
return input;
}
只是为了解释数学在该函数中的作用:
input - 'a'
告诉我们输入的字母表中的位置(假设输入是小写字母)。因此,如果输入为'c'
,那么我们将返回2
。如果输入为'z'
,我们会获得25
。input - 'a' + shift
为我们提供了我们用来制作密码的角色的新位置。请注意,这可能是一个比字母更大的数字(26个字符)。[0 - 25]
。请注意,这仅适用,因为a
到z
和A
到Z
的字符代码是连续的。
答案 1 :(得分:4)
您的计划有三个问题。
程序从argv[1]
和argv[2]
读取,但它假定程序至少接收2个参数。如果它没有收到这么多,那么它可能会崩溃或做任意事情。您应该明确检查程序是否至少(或确切地)收到两个命令行参数:
if (argc != 3) {
fprintf(stdout, "Not enough arguments\n");
exit(1);
}
注意:将arc
重命名为argc
,并且程序名称有一个额外的隐式参数,这就是我们检查3的原因。)
程序将argv[2]
复制到固定大小的缓冲区中。如果消息长度超过255个字符(加上空终止符),那么它可能会覆盖内存并导致任意事情发生。在当前情况下,您可以直接处理argv[2]
的字符,而无需将其复制到临时变量:
for (i = 0; argv[2][i] != '\0' ; i++) {
printf("%c", encrypt(argv[2][i], shift));
}
凯撒班次需要在z或Z之后环绕。见sharth's answer。