c中凯撒密码输出错误



我需要根据一个基本字符串(即字母表)和一个整数来移动给定字符串的字母。
函数的目标是保持在基字符串内
示例:

string to shift: a b c
key: -6
output: u v w

但是我得到:

output: [  ]

这意味着移位是基于ascii表而不是基本字符串完成的。
我想不通为什么?(

下面是代码

#include <stdio.h>
#include <string.h>
void    cesar(char *str, int shift);
int     main(void)
{
char    str[1001] = "ikio kyz rg ykiutjk vgmk ja robxk";
char    temp[1001];
strcpy(temp, str);
printf("%sn", str);
cesar(temp, -6);
return (0);
}
void    cesar(char *str, int shift)
{
char    alphabet[27] = "abcdefghijklmnopqrstuvwxyz";
char    c;
int     i;
i = 0;
while (str[i] != '')
{
if (str[i] >= 'a' && str[i] <= 'z')
{
c = alphabet[i] + (str[i] - alphabet[i] + shift);
str[i] = c;
}
i++;
}
printf("%sn", str);
}

输出:

ceci est la seconde page d[ lire

代替:

ceci est la seconde page du livre

谢谢^ ^

如何实现移位而不产生任何不正确的值

if (str[i] >= 'a' && str[i] <= 'z')
{
c = str[i] - 'a'; // 0 <= c < 26
c += shift;       // any value possible (no limits on `shift`)
while( c < 0 ) c += 26; // no longer negative
while( c > 25 ) c -= 26; // no longer 26+
str[i] = c + 'a';
}

减去a的值将从ASCII常数转换为可以被密码操纵的字母索引(0…25)。在末尾加上a将转换回ASCII。

你的代码所做的是在做%26检查后盲目地向字母添加移位。这意味着在字母表开始之前的字母,需要包裹在字母表末尾的字母(在你的测试用例中是'u'和'v')不会被纠正。

至少这些问题:

'a'形成偏移量

模与剩余

%是余数,而不是欧几里得模。

// Offset from `a`
int c = (str[i] - 'a') + shift;
// modulo
c %= 26; // c now in range -25 to 25
// Handle negative values 
if (c < 26) c += 26;
// Undo the offset  
str[i] = c + 'a';

提示:当shift靠近INT_MAX时,在循环之前执行一次shift %= 26;,以防止(str[i] - 'a') + shift溢出的可能性。
再次使用int c,而不是char c,以防止溢出。

相关内容

  • 没有找到相关文章

最新更新