debugging 用C语言编写的Caesar密码程序存在缺陷

dluptydi  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(139)

我为cs50编写了一个程序,它应该接收一个(整数)key(在运行时)并输出plaintext的提示符,plaintext将根据caesar密码函数输出明文的加密版本。(make caesar),当我在运行时输入“key”时(例如./caesar 2),我得到提示[ Plaintext: ],例如我输入Hello。输出将是[Ciphertext: 99102109109112],而不是预期的[Ciphertext: JGOOQ]
下面是我的代码:

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

// Get the 'key' value at run-time (./ceasar 'key').
// key_value must be a digit/number).
// String argv[1] must be converted to int.
// Prompt user for plaintext.
// plaintext must be converted by casaer cipher to ciphertext.
// Print ciphertext.

// Declaring variables.
string plaintext;
string ciphertext;
int key_value;

// declaring the caesar cipher function (takes in an array of characters (aka string) and an int).
void caesar_cipher(char str[], int shift_value);

int main(int argc, string argv[])
{
    // check if there are two arguments at run-time and the second argument (argv[1]) is a digit.
    if (argc == 2 && isdigit(*argv[1]))
    {
        // convert string argv[s] to an int.
        key_value = atoi(argv[1]);
        // Prompt user for plaintext.
        plaintext = get_string("Plaintext: ");

        printf("Ciphertext: ");

        caesar_cipher(plaintext, key_value);

        // new line
        printf("\n");
        return 0;
    }
    else
    {
        printf("Usage: ./caesar 'key'\n");
        return 1;
    }
}

// char str[] will take in 'plaintext' and int shift_value will take in 'key'
void caesar_cipher(char str[], int shift_value)
{
    int s = 0;
    char c = str[s];

    if (c != '\0')
    {
        // iterate through every character, letter-by-letter.
        for (int i = 0, n = strlen(plaintext); i < n; i++)
        {
            // case for uppercase letters.
            if (isupper(c))
            {
                 printf("%i", (((plaintext[i] - 'A') + shift_value) % 
                        26) + 'Z');
            }
            // case for lowercase letters.
            else if (islower(c))
            {
                printf("%i", (((plaintext[i] - 'a') + shift_value) % 26) 
                       + 'z');
            }
            else
            {
                printf("%c", c);
            }
        }
    }
}
9q78igpj

9q78igpj1#

存在多个问题:

  • 您将转换后的字符作为整数输出(%i),而不是作为字符输出(%c)。
  • 测试if (c != '\0')是冗余的:如果字符串为空,则循环将立即退出。
  • 必须将每个字符存储到循环内的c中才能进行正确操作。
  • 必须将'A'而不是'Z'添加到移位后的索引中。对于小写也存在同样的问题。
  • 该函数应该将其加密为另一个字符串cyphertext,而不是将其打印出来。

以下是修改后的版本:

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

// Get the 'key' value at run-time (./ceasar 'key').
//     key value must be a number.
//     string argv[1] must be converted to int.
// Prompt user for plaintext.
// plaintext must be converted by caesar_cipher to ciphertext.
// Print ciphertext.

char *caesar_cipher(const char *str, int shift_value);

int main(int argc, string argv[]) {
    string plaintext;
    string ciphertext;
    int key_value;

    // check if there are two arguments at run-time and the second argument (argv[1]) is a digit.
    if (argc == 2 && isdigit((unsigned char)*argv[1])) {
        // convert key string argv[1] to an int.
        key_value = atoi(argv[1]);
        // prompt user for plaintext.
        plaintext = get_string("Plaintext: ");
        cyphertext = caesar_cipher(plaintext, key_value);
        printf("Ciphertext: %s\n", cyphertext);
        return 0;
    } else {
        printf("Usage: ./caesar 'key'\n");
        return 1;
    }
}

// The caesar_cipher function:
// takes in a string and a shift value,
// allocate a new string and perform the Caesar transformation in place
// returns the new string.
char *caesar_cipher(const char *str, int shift_value) {
    char *dest = strdup(str);

    // iterate through every character, letter-by-letter.
    for (int i = 0; dest[i] != '\0'; i++) {
        unsigned char c = dest[i];
        // case for uppercase letters.
        if (isupper(c)) {
            c = 'A' + (c - 'A' + shift_value) % 26;
        } else
        if (islower(c)) {
            c = 'a' + (c - 'a' + shift_value) % 26;
        }
        dest[i] = c;
    }
    return dest;
}

相关问题