c 中的分段错误,第 2 周凯撒,cs50x 哈佛课程
Segmentation Error in c, week 2 caesar, cs50x harvard course
所以我在哈佛 cs50 在线课程(2021x 版)的第 2 周。我们应该编写一个程序来加密文本,将每个字母的 ASCII 代码移动一定数量,由用户通过命令行决定。 Here is the full problem. 我快完成了,但是当我尝试 运行 程序时,(它编译得很好),它告诉我有一个 分段错误 .我真的不明白这个问题。我读过这个问题与访问无法访问的特定内存部分有关?我该如何解决这个问题?先感谢您!
这是我的代码..
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[])
{
int k, i;
if (argc == 2 && isdigit(argv[1]) && argv[1] > 0)
{
k = (int) argv[1];
string plaintext = get_string("plaintext: ");
printf("cyphertext: ");
for (i = 0; i < strlen(plaintext); i++)
{
if (islower(plaintext[i]) || isupper(plaintext[i]))
{
printf("%c", (((plaintext[i] + k) - 97) % 26) + 97);
return 0;
}
}
}
else
{
printf("Usage: ./caesar key");
return 1;
}
}
您应该分别检查下位字符和上位字符。
如果角色是低级角色,那你是对的。你应该减去 97.But 如果字符是大写字符你应该减去 65。否则你在模式操作之前得到一个否定的结果,这会导致分段错误。
if(isupper(plainText[i])){
cipherText[i] = (((plainText[i] - 65 + key) % 26) + 65);
} else {
if(islower(plainText[i])){
cipherText[i] = (((plainText[i] - 97 + key) % 26) + 97);
}
}
I'm on week 2 of the harvard cs50 online course
听到这个消息我很难过。你的大部分问题都源于糟糕的 CS-50 class,它欺骗你相信 C 不知何故有一个预制的糖衣字符串 class。它没有,它只有以空终止结尾的原始字符数组,因此大多数字符串操作都是手动的。
其他问题来自编译器向您指出错误时没有听取。这里有一些:
isdigit(argv[1])
没有意义。一个好的编译器会告诉你很多,例如 clang:
warning: cast to smaller integer type 'int' from 'string' (aka 'char *')
您将指针与字符串进行比较,而 isdigit
需要单个字符。为了使用 isdigit
,您必须为字符串的每个字符循环调用它。
argv[1] > 0
没有意义,因为它将指针与 0 进行比较。
error: ordered comparison between pointer and zero
k = (int) argv[1];
也说不通
warning: cast to smaller integer type 'int' from 'string' (aka 'char *')
要将字符串转换为整数,必须使用 strtol
函数,例如 k = strtol(argv[1], NULL, 10)
。它带有您可能也想使用的各种错误处理。
而且因为 k
包含废话 - 实际上它包含一个转换为整数的内存地址,所以 plaintext[i] + k
也变成废话。
if (islower(plaintext[i]) || isupper(plaintext[i]))
没有意义,它说“如果一个字符是小写还是大写”。那么,它可能是?相反,您可能打算使用 toupper
或 tolower
进行大写或小写的所有计算,而不管用户键入什么。
所以我在哈佛 cs50 在线课程(2021x 版)的第 2 周。我们应该编写一个程序来加密文本,将每个字母的 ASCII 代码移动一定数量,由用户通过命令行决定。 Here is the full problem. 我快完成了,但是当我尝试 运行 程序时,(它编译得很好),它告诉我有一个 分段错误 .我真的不明白这个问题。我读过这个问题与访问无法访问的特定内存部分有关?我该如何解决这个问题?先感谢您! 这是我的代码..
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[])
{
int k, i;
if (argc == 2 && isdigit(argv[1]) && argv[1] > 0)
{
k = (int) argv[1];
string plaintext = get_string("plaintext: ");
printf("cyphertext: ");
for (i = 0; i < strlen(plaintext); i++)
{
if (islower(plaintext[i]) || isupper(plaintext[i]))
{
printf("%c", (((plaintext[i] + k) - 97) % 26) + 97);
return 0;
}
}
}
else
{
printf("Usage: ./caesar key");
return 1;
}
}
您应该分别检查下位字符和上位字符。 如果角色是低级角色,那你是对的。你应该减去 97.But 如果字符是大写字符你应该减去 65。否则你在模式操作之前得到一个否定的结果,这会导致分段错误。
if(isupper(plainText[i])){
cipherText[i] = (((plainText[i] - 65 + key) % 26) + 65);
} else {
if(islower(plainText[i])){
cipherText[i] = (((plainText[i] - 97 + key) % 26) + 97);
}
}
I'm on week 2 of the harvard cs50 online course
听到这个消息我很难过。你的大部分问题都源于糟糕的 CS-50 class,它欺骗你相信 C 不知何故有一个预制的糖衣字符串 class。它没有,它只有以空终止结尾的原始字符数组,因此大多数字符串操作都是手动的。
其他问题来自编译器向您指出错误时没有听取。这里有一些:
isdigit(argv[1])
没有意义。一个好的编译器会告诉你很多,例如 clang:warning: cast to smaller integer type 'int' from 'string' (aka 'char *')
您将指针与字符串进行比较,而
isdigit
需要单个字符。为了使用isdigit
,您必须为字符串的每个字符循环调用它。argv[1] > 0
没有意义,因为它将指针与 0 进行比较。error: ordered comparison between pointer and zero
k = (int) argv[1];
也说不通warning: cast to smaller integer type 'int' from 'string' (aka 'char *')
要将字符串转换为整数,必须使用
strtol
函数,例如k = strtol(argv[1], NULL, 10)
。它带有您可能也想使用的各种错误处理。而且因为
k
包含废话 - 实际上它包含一个转换为整数的内存地址,所以plaintext[i] + k
也变成废话。if (islower(plaintext[i]) || isupper(plaintext[i]))
没有意义,它说“如果一个字符是小写还是大写”。那么,它可能是?相反,您可能打算使用toupper
或tolower
进行大写或小写的所有计算,而不管用户键入什么。