我是一名新程序员,试图通过做CS50的pset来自学。我编写了以下代码,可以正常工作。

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


string vencipher(string text, string key)
{
    for (int i=0, j=0, n =strlen(text); i < n; i++,j++)
    {
        int m = strlen(key);
        if (text[i] >= 65 && text[i] <= 90 && key[j % m] >= 65 && key[j % m] <= 90)
        {
            text[i] = 65 + ((text[i] - 65) + (key[j % m] - 65)) % 26;
        }
        else if (text[i] >= 65 && text[i] <= 90 && key[j % m] >= 97 && key[j % m] <= 123)
        {
            text[i] = 65 + ((text[i] - 65) + (key[j % m] - 97)) % 26;
        }
        else if (text[i] >= 97 && text[i] <= 123 && key[j % m] >= 65 && key[j % m] <= 90)
        {
            text[i] = 97 + ((text[i] - 97) + (key[j % m] - 65)) % 26;
        }
        else if (text[i] >= 97 && text[i] <= 123 && key[j % m] >= 97 && key[j % m] <= 123)
        {
            text[i] = 97 + ((text[i] - 97) + (key[j % m] - 97)) % 26;
        }
        else
        {
            text[i] = text[i];
            j = j - 1;
        }
    }
    return text;
 }

int keyvalidator(string text)
{
    int alphalen = 0;
    for (int i=0, n=strlen(text); i < n; i++)
    {
        if ((text[i] >= 97 && text[i] <= 123) || (text[i] >= 65 && text[i] <= 90))
        {
            alphalen = alphalen + 1;
        }
    }
    if (alphalen == strlen(text))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main(int argc, string argv[])
{
    if (argc != 2 || keyvalidator(argv[1]) != 1)
    {
        printf("That is not a valid secret key!\n");
        return 1;
    }

    if (argc == 2)
    {
        string secretKey = argv[1];
        string plainText = GetString();
        printf("%s\n", vencipher(plainText, secretKey));
    }
    return 0;
}


我想尝试将加密算法分解为一些不同的方法,以尝试提高代码的可读性。这就是我所做的

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

string keycaseID(string key)
{
    for (int i=0, n=strlen(key); i < n; i++)
    {
        if (key[i] >= 65 && key[i] <= 90)
        {
            key[i] = 1;
        }

        else
        {
            key[i] = 0;
        }
    }
    return key;
}

string setkeycase(string key)
{
    for (int i=0, n=strlen(key); i < n; i++)
    {
        if (keycaseID(key)[i] == 1)
        {
            key[i] = key [i] - 65;
        }
        else if (keycaseID(key)[i] == 0)
        {
            key[i] = key [i] - 97;
        }
    }
    return key;
}

string vencipher(string text, string key)
{
    for (int i=0, j=0, n =strlen(text); i < n; i++,j++)
    {
        int m = strlen(key);
        if (text[i] >= 65 && text[i] <= 90 && keycaseID(key)[j % m] == 1)
        {
            text[i] = 65 + ((text[i] - 65) + setkeycase(key)[j % m]) % 26;
        }
        else if (text[i] >= 65 && text[i] <= 90 && keycaseID(key)[j % m] == 0)
        {
            text[i] = 65 + ((text[i] - 65) + setkeycase(key)[j % m]) % 26;
        }
        else if (text[i] >= 97 && text[i] <= 123 && keycaseID(key)[j % m] == 1)
        {
            text[i] = 97 + ((text[i] - 97) + setkeycase(key)[j % m]) % 26;
        }
        else if (text[i] >= 97 && text[i] <= 123 && keycaseID(key)[j % m] == 0)
        {
            text[i] = 97 + ((text[i] - 97) + setkeycase(key)[j % m]) % 26;
        }
        else
        {
            text[i] = text[i];
            j = j - 1;
        }
    }
    return text;
 }

int keyvalidator(string text)
{
    int alphalen = 0;
    for (int i=0, n=strlen(text); i < n; i++)
    {
        if ((text[i] >= 97 && text[i] <= 123) || (text[i] >= 65 && text[i] <= 90))
        {
            alphalen = alphalen + 1;
        }
    }
    if (alphalen == strlen(text))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main(int argc, string argv[])
{
    if (argc != 2 || keyvalidator(argv[1]) != 1)
    {
        printf("That is not a valid secret key!\n");
        return 1;
    }

    if (argc == 2)
    {
        string secretKey = argv[1];
        string plainText = GetString();
        printf("%s\n", vencipher(plainText, secretKey));
    }
    return 0;
}


较新的代码可以编译,但是运行它时,我会收到“浮点异常”,根据我的研究,这是模除以0的结果。我搜索了几次代码,但找不到除以的任何实例0.我想知道是否有人可以帮助我找到我的错误并向我解释是什么导致了浮点异常。

最佳答案

我还看到了内存损坏的浮点异常,因此这很可能是由于代码中的任何地方都没有/字符。

我会告诉你你做错了什么。通过多次在同一字符串上调用keycaseID()(就像在setkeycase()中所做的那样,可以确保最后得到一个全零的字符串(0而不是'0')。

第一次,它将根据其大小写将所有元素转换为1或0(因此您将丢失其原始值)。第二次,因为它们都是01,它们将小于65,因此都设置为0。

假设您的密钥全是字母字符(大写或小写),则可以使用如下所示将其转换为0到25的值:

for (int i = strlen (key) - 1; i >= 0; i--)  // needs string.h
    if (isupper (key[i]))                    // needs ctype.h
        key[i] -= 'A';
    else
        key[i] -= 'a';


或者,甚至更短:

for (int i = strlen (key) - 1; i >= 0; i--)  // needs string.h
    key[i] = toupper (key[i]) - 'A';         // needs ctype.h


这些都不是完美可移植的,因为C并不要求A-Z是连续的代码点,但是,只要您避开了奇怪的非ASCII环境,就可以了:-)

关于c - CS50-调用方法时出现浮点异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24522881/

10-11 17:21