使用来自 cs.50.h 的“string”的 C 代码中的分段错误

Segmentation fault in C code using `string` from cs.50.h

我这里有一个程序,我试图使用 ceasar 密码对一串字母进行解码;本质上,我将字符串 "down" 中的每个字符移动一个字母 ("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;
}

为什么 string 对于 ?, here you can see an example. You are modifying a string literal and you shouldn't. Doing it invokes undefined behavior. Instead of having a string type you should treat strings as what they are in 中的类型是个坏主意。

不如这样

char secret_message[] = "ueuag rKJ AGIQ GIAR FEgN";

解码函数

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

    for (i = 0; message[i] != '[=11=]'; 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;
}

如您所见,我将字符串视为一个数组,因为它就是一个以 '[=15=]' 结尾的字节数组。如果你知道这一点,你永远不会做像 typedef char * string 这样的事情,因为它非常具有误导性。

cs50.hstring是一个typedef表示一个char指针,指针不是字符串,一个字符串是一个字节序列,一个 char * 指针可以指向一个 char 的数组,如果你定义它并正确初始化它,它可能是一个字符串。但是 char * 指针可以指向字符串文字,如果将其定义为

则无法更改它们,这一点尚不清楚
string string_literal = "Do not attempt to modify me, it's undefined behavior";

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

此外,在我看来 typedefing 指针根本没有任何好处并且会引起很多混乱,指针是指针并且在声明时必须在它的标识符附近有一个 *,如果您删除了对 * 的需要,您很容易忽略代码中的指针并感到困惑。