gpt4 book ai didi

CS50 Pset2-凯撒密码

转载 作者:太空宇宙 更新时间:2023-11-04 04:11:55 25 4
gpt4 key购买 nike

它没有显示我想要它显示的是输入文本的加密版本,而是符号,正如我猜的那样,看起来有点像“?”作为终端中的输出出现。谁能帮我找出我遗漏或做错了什么?

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

int main(int argc, string argv[])
{
if (argc == 2)
{
string ptext = get_string("plaintext: ");
int key = (int) argv[1];
printf("ciphertext: ");
for (int i = 0, n = strlen(ptext); i < n; i++)
{
printf("%c", (( ptext[i] + key ) % 26);
}
printf("\n");
}
else
{
printf("Invalid input. \n");
}

}

我希望“hello”的输出是“ifmmp”,但事实并非如此。

最佳答案

这段代码是错误的:

int key = (int) argv[1];

argvstring的数组,在 CS50 中只不过是一个混淆的char *指针。

根据5.1.2.2.1 Program startup of the C standard:

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

    int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

    int main(int argc, char *argv[]) { /* ... */ }

or equivalent; ...

因此argv[1]是一个char *指针值,然后您将其分配给int值。这是获取一些内存的地址(比如argv[1]中的值是0xFF0403220020480C)并试图将其填充到int变量key的可能 4 个字节中(在这种情况下将被分配截断值0x0020480C.)

这不是您想要做的。

(IMO,你这里的问题是一个完美的例子,说明了为什么 CS50 将char *string类型混淆是一个非常糟糕的主意。如果不理解指针和NUL终止的char 字符串通过char *指针访问,而string所做的混淆使得这更难。)

如果你想要convert a string to a numeric value,你可能想要something like strtol() (never use atoi() as it has no error checking and its use can invoke undefined behavior):

char firstCharNotConverted;

// set errno to zero as strtol()
errno = 0;
long key = strtol( argv[ 1 ], &firstCharNotConverted, 0 );

// if errno is now non-zero, the call to strtol() failed (per Linux man page)
// need to examine key and the contents of firstCharNotConverted
// to figure out why
if ( errno != 0 )
{
...
}

省略了适当的 header ,作为尝试使用此代码的任何人的练习 ;-)

请注意,我将long用作key,因为如果将返回值强制转换为strtol(),则无法对int进行完整且正确的错误检查。

错误检查strtol()可能有点复杂,因为返回的值(并在上面的代码中分配给key)可以是任何值,并且没有可能的值不是long的合法值strtol() ”可以返回以指示错误,因此为了进行正确的错误检查,您需要检查errnofirstCharNotConverted的值,以正确确定是否确实发生了错误。 Linux man page声明:

Since strtol() can legitimately return 0, LONG_MAX, or LONG_MIN (LLONG_MAX or LLONG_MIN for strtoll()) on both success and failure, the calling program should set errno to 0 before the call, and then determine if an error occurred by checking whether errno has a nonzero value after the call.

在调用strtol()之后,您需要检查key是否为LONG_MIN,或LONG_MAXerrno等于ERANGE是否为下溢或上溢,或者key是否为0 ”您需要检查firstCharNotConverted的内容以确定转换失败的原因。请注意,如果key为零且firstCharNotConverted不等于argv[ 1 ],则输入字符串已从零正确转换。

您的 Ceaser 密码实现也是错误的:

    for (int i = 0, n = strlen(ptext); i < n; i++)
{
printf("%c", (( ptext[i] + key ) % 26);
}
printf("\n");

将只打印出值从025的字符——它们不是 ASCII 字符集中的字母。

这里已经发布了很多 Ceaser 密码问题,所以我不打算编写代码。一个示例问题请参见Caesar's Cipher Code

关于CS50 Pset2-凯撒密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56272562/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com