使用来自 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
对于 c?, 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 c 中的类型是个坏主意。
不如这样
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.h中string
是一个typedef
表示一个char
指针,指针不是字符串,一个字符串是一个字节序列,一个 char *
指针可以指向一个 char
的数组,如果你定义它并正确初始化它,它可能是一个字符串。但是 char *
指针可以指向字符串文字,如果将其定义为
则无法更改它们,这一点尚不清楚
string string_literal = "Do not attempt to modify me, it's undefined behavior";
在声明指向字符串文字的指针时,您应该使用 const char *
以避免意外地尝试修改它。
此外,在我看来 typedef
ing 指针根本没有任何好处并且会引起很多混乱,指针是指针并且在声明时必须在它的标识符附近有一个 *
,如果您删除了对 *
的需要,您很容易忽略代码中的指针并感到困惑。
我这里有一个程序,我试图使用 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
对于 c?, 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 c 中的类型是个坏主意。
不如这样
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.h中string
是一个typedef
表示一个char
指针,指针不是字符串,一个字符串是一个字节序列,一个 char *
指针可以指向一个 char
的数组,如果你定义它并正确初始化它,它可能是一个字符串。但是 char *
指针可以指向字符串文字,如果将其定义为
string string_literal = "Do not attempt to modify me, it's undefined behavior";
在声明指向字符串文字的指针时,您应该使用 const char *
以避免意外地尝试修改它。
此外,在我看来 typedef
ing 指针根本没有任何好处并且会引起很多混乱,指针是指针并且在声明时必须在它的标识符附近有一个 *
,如果您删除了对 *
的需要,您很容易忽略代码中的指针并感到困惑。