即使我可以编译我的代码,也会出现分段错误(CS50 第 2 周替换问题)

Segmentation fault even though I can compile my code (CS50 week 2 substitution problem)

即使我可以在这里编译我的代码,如果我 运行 这段代码,它会说 'segmentation fault.' 我正在尝试加密消息。更多详情:https://cs50.harvard.edu/x/2021/psets/2/substitution/

我的代码有问题吗?

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

int main(int argc, string argv[])
{
    if(argc == 2) 
    {
        if(isalpha(argv[1]))
        {
            if(strlen(argv[1]) == 26)
            {
                char lower[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
                char upper[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
        
                string plaintext = get_string("plaintext: ");
        
                for(int k = 0, n = strlen(plaintext); k < n; k++)
                {
                    for(int i = 0; i < 26; i++)
                    {   
                    
                        if(plaintext[k] == upper[i])
                        {
                            upper[i] = argv[1][i];
                            printf("%c", argv[1][i]);
                        }
                        else if(plaintext[k] == lower[i])
                        {
                            lower[i] = argv[1][i];
                            printf("%c", argv[1][i]);
                        }
                        else
                        {
                            printf("%c", plaintext[k]);
                        }
                    }
                }
                printf("\n");
                return 0;
            }
            else
            {
                printf("Key must contain 26 characters.\n");
                return 1;
            }
        }
        else
        {
            printf("Key must contain 26 characters.\n");
            return 1;
        }
    }
    else 
    {
        printf("Usage: ./substitution key\n");
        return 1;
    }
}

此处 isalpha(argv[1]) 您传递了一个指针(即 argv[1]),但 isalpha 期望 char.

此外,您的代码比需要的复杂得多。一种更简单的方法是从纯文本计算密钥的索引。

示例:

如果一个纯文本字母是'B',你想得到密钥中的第二个字母。要做到这一点,只需执行 index = 'B' - 'A',即索引将为 1。编码后的字母将为 toupper(argv[1][1]).

如果一个纯文本字母是'C',你想得到密钥中的第二个字母。要做到这一点,只需执行 index = 'C' - 'A',即索引将为 2。编码后的字母将为 toupper(argv[1][2]).

所以在代码中是这样的:

            if (isupper(plaintext[k]))
            {
                int index = plaintext[k] - 'A';
                result[k] = toupper(argv[1][index]);
            }
 

如果一个纯文本字母是'b',你想得到密钥中的第二个字母。要做到这一点,只需执行 index = 'b' - 'a',即索引将为 1。编码后的字母将为 tolower(argv[1][1]).

如果一个纯文本字母是'c',你想得到密钥中的第二个字母。要做到这一点,只需执行 index = 'c' - 'a',即索引将为 2。编码后的字母将为 tolower(argv[1][2]).

            if (islower(plaintext[k]))
            {
                int index = plaintext[k] - 'a';
                result[k] = tolower(argv[1][index]);
            }

拼起来(固定纯文本):

int main(int argc, char* argv[])
{
    if(argc != 2) 
    {
        printf("Usage: ./substitution key\n");
        return 1;
    }
    
    if(strlen(argv[1]) != 26)
    {
        printf("Key must contain 26 characters.\n");
        return 1;
    }

    char plaintext[30] = "HeLlO woRLd";
    char result[30] = {0};
    for(int k = 0, n = strlen(plaintext); k < n; k++)
    {
        if (isupper(plaintext[k]))
        {
            result[k] = toupper(argv[1][plaintext[k] - 'A']);
        }
        else if (islower(plaintext[k]))
        {
            result[k] = tolower(argv[1][plaintext[k] - 'a']);
        }
        else
        {
            result[k] = plaintext[k];
        }
    }
    puts(result);
    return 0;
}

输出:

EhBbQ pqLBs