为什么我的Caesar解决方案(CS50)重复输入大写字符?

时间:2020-07-05 22:46:24

标签: c cs50

我的程序可以正确加密小写字母,但对于大写字母,输出将是双字符。例如,如果我输入为“ BARFOO”,则程序将输出“ EBDAURIFRORO”。代码如下所示。

printf("ciphertext: ");
for (int i = 0, n = strlen(plain); i < n; i++) 
{
    if (isalpha(plain[i]) && isupper(plain[i])) //problem must be here
    {
        int c = 65;
        printf("%c", (plain[i] - c + key) % 26 + c); 
    }
    
    if (isalpha(plain[i]) && islower(plain[i])) //this works
    {
        int c = 97;
        printf("%c", (plain[i] - c + key) % 26 + c);
    }
    
    else //this preserves punctuation, space, etc.
    {
        printf("%c", plain[i]);
    }
}
printf("\n");

我要在第一个if循环中尝试做的是检查大写字母字符。然后,我遍历每个字符,将其转换为字母索引,其中“ A”的索引为[0],B的索引为[1],依此类推。最后,您可以看到我将其转换回了Ascii索引。为什么只用大写字母呢?我的数学错了吗?对于小写字母,数学原理基本相同,但行为应有。我以为这是我的for循环的问题,但我不确定该如何更改。

1 个答案:

答案 0 :(得分:1)

您的第一个“如果”是独立的。因此,当输入为大写时,它将编码并在第一个“ if”中显示,然后绕过并在“ else”中显示,因为它不是大写。

您可以使“ else”仅绕过每个非字母字符,而不是仅绕过非小写字符来解决此问题,例如:

printf("ciphertext: ");
for (int i = 0, n = strlen(plain); i < n; i++)
{
    if (isalpha(plain[i]))
    {
        if(isupper(plain[i])) //problem must be here
        {
            int c = 65;
            printf("%c", (plain[i] - c + key) % 26 + c);
        }else{
            int c = 97;
            printf("%c", (plain[i] - c + key) % 26 + c);
        }

    }else //this preserves punctuation, space, etc.
    {
        printf("%c", plain[i]);
    }
}
printf("\n");