使用cs.50.h中的`string`分割C代码中的错误

Dav*_*ess 2 c segmentation-fault caesar-cipher cs50

我在这里有一个程序,我正在尝试使用ceasar密码解码一串字母; 本质上我将字符串中的每个字符"向下"移动一个字母("a" - >"b","f" - >"g","z" - >"a").

我移动一封信的数量取决于我给它的关键.

在这个特定的程序中,我有一个秘密编码的消息硬编码到main()函数中,一个for循环遍历每个可能的密钥.

这个想法是,如果这个秘密信息只是向下移动了x个字母,吐出25个版本的密码将揭示一个可理解的答案.

不幸的是,我正在使用一些对我来说很新的概念 - argc,argv和一个程序中的多个函数.我对此很新.

有人可以帮我解释我得到的分段错误错误吗?我认为我没有引起任何参数溢出.

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

string decode(int key, string message);

int main(void)
{
    string secret_message = "ueuag rKJ AGIQ GIAR FEgN";

    for (int i = 0; i < 25; i++)
    {
        decode(i, secret_message);
        printf("%s", secret_message);
    }

    return 0;
}

string decode(int key, string message)
{
    int i;

    for (i = 0; i < strlen(message); i++)
    {
        if (message[i] >= 'a' && message[i] <= 'z')
        {
            message[i] = ((message[i] - 97 + key) % 26) + 97;
        }
        else if (message[i] >= 'A' && message[i] <= 'Z')
        {
            message[i] = ((message[i] - 65 + key) % 26) + 65;
        }
    }

    return message;
}
Run Code Online (Sandbox Code Playgroud)

Iha*_*imi 7

为什么string的类型是个坏主意?在这里你可以看到一个例子.您正在修改字符串文字而不应该.这样做会调用未定义的行为.你应该把字符串视为字符串而不是类型.string

而是这样做

char secret_message[] = "ueuag rKJ AGIQ GIAR FEgN";
Run Code Online (Sandbox Code Playgroud)

和解码功能

char *decode(int key, char *message)
{
    int i;

    for (i = 0; message[i] != '\0'; i++)
    {
        if (message[i] >= 'a' && message[i] <= 'z')
        {
            message[i] = ((message[i] - 97 + key) % 26) + 97;
        }
        else if (message[i] >= 'A' && message[i] <= 'Z')
        {
            message[i] = ((message[i] - 65 + key) % 26) + 65;
        }
    }

    return message;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我将字符串视为一个数组,因为它就是这样,一个带有a的字节数组'\0'.如果你知道这一点,你就永远不会做那样的事情,typedef char * string因为它会产生误导.

cs50.h string是一个typedef用于一个char指针,和一个指针不是字符串,字符串是字节序列和一个char *指针可以指向数组的char可以是一个字符串,如果你把它定义和正确地初始化.但是char *指针可以指向一个字符串文字,你不能改变它们,如果你把它定义为不明确的话

string string_literal = "Do not attempt to modify me, it's undefined behavior";
Run Code Online (Sandbox Code Playgroud)

在声明指向字符串文字的指针时,您应该使用const char *以避免意外尝试修改它.

另外,typedef在我看来,ing指针根本没有任何好处并且引起很多混乱,指针是一个指针,并且*在声明时必须有一个接近它的标识符,如果你删除了a的需要*你可以很容易地忽略代码中的指针和感到困惑.