-2

伙计们,我在某个网站上发现了这个凯撒密码……但是当我运行它时,它在在线编译器中显示分段错误……但是在 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;
}
4

3 回答 3

4

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

可以假设该函数返回一个布尔值 1 或 0,但是如果您查看文档,如果 c 确实是一个大写字母,isupper()它会说A value different from zero (ie, true)。否则为零(即假)。isupper()这以及返回 int 而不是 _Bool 的事实导致了问题。

int isupper ( int c );

返回 true 时isupper()可能会返回任何 non_zero 值。在我的情况下,它返回8(一个特定的位域)。在你的情况下可能是一样的。

您所要做的就是将isupper()返回_Bool

printf("%d   %d" ,(_Bool)isupper('A') , ((int)(tolower(str[i])-'a')+c)%26 ) ;
于 2013-07-01T09:29:21.033 回答
0

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

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

alpha[isupper(str[i]) ? 1 : 0][...]
于 2013-07-01T09:29:19.343 回答
0

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

isupper 返回:如果 c 确实是大写字母,则返回一个不同于零的值(即 true)。否则为零(即假)。

alpha[isupper(str[i]) != 0][...]会成功的

另请注意,您应该始终将传递给 isupper()、isalnum() 等的参数转换为 unsigned char

于 2013-07-01T09:33:01.827 回答