Cesar Cipher在Array中超出范围

时间:2013-07-01 09:17:25

标签: c

伙计们我在某些网站上发现了这个凯撒密码....但是当我运行它在线编译器中显示分段错误时...但在c编译器中我正在使用它显示处理器故障...任何人都可以在这段代码中指出错误

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define caesar(x) rot(13, x)
#define decaesar(x) rot(13, x)
#define decrypt_rot(x, y) rot((26-x), y) 

void rot(int c, char *str)
{
    int l = strlen(str);
    const char *alpha[2] = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"};

    int i;
    for (i = 0; i < l; i++)
    {
        if (!isalpha(str[i]))
            continue;

        str[i] = alpha[isupper(str[i])][((int)(tolower(str[i])-'a')+c)%26];
    }
}

int main()
{
    char str[] = "This is a top secret text message!";

    printf("Original: %s\n", str);
    caesar(str);
    printf("Encrypted: %s\n", str);
    decaesar(str);
    printf("Decrypted: %s\n", str);

    return 0;
}

3 个答案:

答案 0 :(得分:4)

您的代码是正确的,除了一个细节,这可能会让新手感到困惑。

可以假设函数isupper()返回布尔值1或0,但是如果你检查文档它会说一个不等于零的值(即真)如果确实c是一个大写字母。否则为零(即假)。 这个以及isupper()返回int而不是_Bool的事实导致了这个问题。

int isupper ( int c );

返回true isupper()时可能会返回任何非零值。在我的例子中,它返回8(一个特定的位字段)。你的可能也一样。

您所要做的就是将isupper()的回复投放到_Bool

printf("%d   %d" ,(_Bool)isupper('A') , ((int)(tolower(str[i])-'a')+c)%26 ) ;

答案 1 :(得分:0)

问题很可能是您使用isupper作为索引。它不能保证返回1的真值,只是它会返回“true”(可能是任何非零值)。

您可以使用三元表达式解决此问题:

alpha[isupper(str[i]) ? 1 : 0][...]

答案 2 :(得分:0)

在循环的第一次迭代中,您尝试写入alpha[256][6],(isupper并不总是返回01

  

isupper返回:如果确实c是a,则值不为零(即,为真)   大写字母。否则为零(即假)。

alpha[isupper(str[i]) != 0][...]会做到这一点

另请注意,您应始终投射您传递给的参数 isupper(),isalnum()等等到unsigned char