【问题标题】:Segmentation fault even though I can compile my code (CS50 week 2 substitution problem)即使我可以编译我的代码也会出现分段错误(CS50 第 2 周替换问题)
【发布时间】:2021-08-05 18:46:21
【问题描述】:

即使我可以在此处编译我的代码,但如果我运行此代码,它会显示“分段错误”。我正在尝试加密消息。更多详情: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]) 是错误的。 isalpha() 的参数是 char,但 argv[1]char*
  • 为什么要修改循环中的upperlower 数组?
  • 如果你想检查argv[1]是否全是字母,你必须遍历整个字符串,在每个字符上调用isalpha()

标签: c segmentation-fault cs50


【解决方案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

【讨论】:

  • 我看不懂这里的行:char plaintext[30] = "HeLlO woRLd";字符结果[30] = {0};为什么在这里说这些?
  • 哎呀!我想我知道原因。谢谢您的帮助。真的很感激。
猜你喜欢
  • 2022-12-11
  • 2020-02-24
  • 2021-07-28
  • 1970-01-01
  • 2020-07-04
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多