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

时间:2016-02-13 00:53:05

标签: c segmentation-fault cs50 caesar-cipher

我在这里有一个程序,我试图使用ceasar密码解码一串字母;基本上我是在移动字符串中的每个字符" down"一封信(" a" - >" b"," f" - >" g"," z&#34 ; - >" 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;
}

1 个答案:

答案 0 :(得分:7)

string为什么string中的类型不好?,在这里您可以看到一个示例。您正在修改字符串文字而不应该。这样做会调用未定义的行为。您应该将字符串视为中的字符串,而不是char secret_message[] = "ueuag rKJ AGIQ GIAR FEgN"; 类型。

而是像这样做

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;
}

解码功能

'\0'

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

cs50.h中 typedefchar指针的char *,指针不是字符串,字符串是字节序列并且char指针可以指向char *的数组,如果您定义它并正确初始化它,它可以是一个字符串。但是string string_literal = "Do not attempt to modify me, it's undefined behavior"; 指针可以指向字符串文字,如果将其定义为

,则无法更改它们。
const char *

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

另外,在我看来*指针根本没有任何好处并且引起很多混淆,指针是一个指针,并且在声明时必须有一个*附近的标识符,如果你删除需要一个 <input id="isc_B" class="selectItemText" type="TEXT" tabindex="1131" style="width:66px;height:12px;-moz-user-focus:normal;" autocomplete="OFF" onselect="if (window.isc_ComboBoxItem_0 == null) return;isc_ComboBoxItem_0.$54h()" oninput="isc_ComboBoxItem_0._handleInput()" spellcheck="true" $377="$378" $376="isc_ComboBoxItem_0" handlenativeevents="false" name="valueField"/> 你可以很容易地忽略代码中的指针而感到困惑。