我正在尝试对字符 z (ASCII 122) 执行凯撒移位。我如何给它 "more room" 以防止它超过 127?

I am trying to perform a Caesar shift on the character z (ASCII 122). How do I give it "more room" to prevent it from overflowing past 127?

在 CS50 2019 凯撒作业中,我应该对字符执行给定字母数 (key) 的凯撒移位。

为此,我将 key 的值添加到每个字母,例如:

for each character in plaintext:
    plaintext[character] += key

因为我想让z循环回到a,所以我写道:

while (ciphered_character > 122)
{
    ciphered_character -= 26;
}

运行 zplaintext26key 的程序导致 26 添加到 z(用 122 表示)。这会导致 plaintext[character] 溢出(超过 127,我想)并在 while 循环甚至开始之前变为负值。这会产生垃圾输出。

我知道我可以事先检查潜在的溢出并先减去 26,但这会使我的代码复杂化。我可以给变量 'more room' 来防止它溢出吗?

我是否使用不同的数据类型?这里的最佳做法是什么?

如果您只关心小写字母,那么这对您有用:

for each character in plaintext:
   plaintext[character] = (plaintext[character] - 'a' + key) % 26 + 'a'

减去 'a' 得到 0-25 的值,然后添加密钥。如果出现溢出,模数将为您提供 0-25 范围内的更新值,该值将添加回 'a' 以获得正确的字符。

如果您确实需要处理大小写,那么您将需要两种不同的情况 - 一种使用 'a',另一种使用 'A'。 Select 通过检查 isupper(plaintext[character])

每个字符的正确大小写

有趣的项目;

我像 this 那样做了,假设是 ASCII 并使用了从 Space~

的所有可打印字符
void caeser_shift(char* text, int key)
{ while (*text) { *text++ = ((*text-' ') + key) %('~'-' ') + ' '; } }

int main(void)
{
    char plaintext[] = "Hello World; This is a test.";

    caeser_shift(plaintext, 26);

    printf("%s\n", plaintext);

    return 0;
}

输出

Success #stdin #stdout 0s 4520KB
b!((+:q+.( U:n$%/:%/:{:0!/0H