C语言 尝试在argv[1]上使用strlen时出现分段错误

gjmwrych  于 2023-06-28  发布在  其他
关注(0)|答案(1)|浏览(131)

我一直在尝试cs50的课程(这门课程是我第一次介绍c,请发发慈悲),并得到了替代问题。我已经坚持了一段时间了。这是我的bug代码:

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

int check(string str);

int main(int argc, string argv[])
{

    if(argc < 1 || argc > 2)
    {
        printf("Usage: ./substitution key");
        return 1;
    }

    string key = argv[1];

    if(check(key) == 1)
    {
            return 1;
    }


    string plaintext = get_string("plaintext:");
    int lenght = strlen(plaintext);
    char ciphertext[lenght + 1];

    for(int i = 0; i <= lenght; i++)
    {
        if(islower(plaintext[i]))
        {
            plaintext[i] -= 97;
            ciphertext[i] = key[(int)plaintext[i]];
            if(isupper(ciphertext[i]))
            {
                ciphertext[i] = tolower(ciphertext[i]);
            }
        }

        if(isupper(plaintext[i]))
        {
            plaintext[i] -= 65;
            ciphertext[i] = key[(int)plaintext[i]];
            if(islower(ciphertext[i]))
            {
                ciphertext[i] = toupper(ciphertext[i]);
            }
        }
    }

    printf("ciphertext:%s", ciphertext);



}



int check(string str)
{
    //controlle del numero di lettere, che i caratteri della chiave non siano ripetuti o numerici hahahahah lol
   char alphabet[26] = {'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'};
   int count[26] = { 0 };
   if(strlen(str) != 26)
   {
    printf("Key must contain 26 characters.");
    return 1;
   }
   for(int i = 0; i < 25; i++)
   {
        if(isalpha(str[i]) == 0)
        {
            return 1;
        }

        str[i] = (char)tolower(str[i]);

        for(int j = 0; j < 25; j++)
        {
            if(str[i] == alphabet[j])
            {
                count[j] += 1;
            }

        }
    }

    for(int i = 0; i < 25; )
    {
        if(count[i] != 1)
        {
            return 1;
        }
    }

    return 0;

}

主要的问题是,似乎不可能通过存储来将argv[1]作为字符串处理,因为每当我运行程序时,它都会无休止地运行。
这是我在调试控制台上得到的分段错误:Program received signal SIGSEGV, Segmentation fault. __strlen_evex () at ../sysdeps/x86_64/multiarch/strlen-evex.S:77
当我尝试调试时,它说在尝试使用strlen()获取键长度时发生了分段错误。调试的时候也是这样,它说key已经存储了0x0,所以也许我在把argv[1]赋值给key的时候也弄错了。我认为argv[1]可能不是以一个
空字符,但我不确定,因为我只知道基本的c。

rkue9o1l

rkue9o1l1#

尝试更改:

if(argc < 1 || argc > 2)

致:

if(argc != 2)

@SomeProgrammerDude评论道。请记住:

  • argc是命令行上的参数数(包括程序名本身)
  • argv是一个C风格的字符串数组(字符数组,每个字符串的末尾都有一个空字符)
  • argv[0]是正在执行的程序的名称
  • argv[1]是命令行上提供的第一个参数
  • argv[2]是命令行提供的第二个参数,依此类推。

此外,在check()中,你假设str的长度为25,由此判断:

for(int i = 0; i < 25; i++)
{
     if(isalpha(str[i]) == 0)
     ...

记住C字符串是以NULL结尾的,所以你应该这样做:

for(int i = 0; str[i] != 0; i++)
{
     if(isalpha(str[i]) == 0)
     ...

为了不超出str的边界。

相关问题