CS50 pset2 替换
CS50 pset2 substitution
挑战在于创建一个程序,您可以在其中输入一个 26 个字符长的字符串,基本上可以替换字母表。因此,例如,如果您将密钥设置为“qwertyuiopasdfghjklzxcvbnm”,它将使用 q 表示 a,w 表示 b,e 表示 c,r 表示 d,等等。然后您输入一个字符串作为您的消息,它将明文转换为密文。
到目前为止,在课程中我们还没有涉及指针,所以我想人们应该能够在不使用 * 或 & 来引用指针的情况下完成这一挑战。相反,我们被告知使用允许我们使用“字符串”的库,而库则处理在后台为我们使用指针的技术性工作。不过我对此有点困惑,因为我最初尝试的代码是这样的:
{
if(isupper(plainText[i]))
{
cypherText[i] = key[plainText[i] - 'A'];
}
else if (islower(plainText[i]))
{
cypherText[i] = key[plainText[i] - 'a'];
}
}
printf("%s\n", cypherText);
但我收到以下错误:
error: incompatible integer to pointer conversion assigning to 'string' (aka 'char *') from 'char'; take the address with & [-Werror,-Wint-conversion]
cypherText[i] = key[plainText[i] - 'A'];
^ ~~~~~~~~~~~~~~~~~~~~~~~
&
error: incompatible integer to pointer conversion assigning to 'string' (aka 'char *') from 'char'; take the address with & [-Werror,-Wint-conversion]
cypherText[i] = key[plainText[i] - 'a'];
^ ~~~~~~~~~~~~~~~~~~~~~~~
&
error: format specifies type 'char *' but the argument has type 'string *' (aka 'char **') [-Werror,-Wformat]
printf("%s\n", cypherText);
所以我把代码改成了下面的
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string key;
do
{
key = get_string("Key:");
}
while(strlen(key) != 26);
string plainText = get_string("Text:");
string cypherText[strlen(plainText)];
for (int i = 0; plainText[i] != '[=12=]'; i++)
{
if(isupper(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'A'];
}
else if (islower(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'a'];
}
}
printf("%s\n", *cypherText);
}
现在它编译了但没有按预期工作,而且这个错误不是我通过调试能够识别的。基本上当我 运行 使用键“bcdefghijklmnopqrstuvwxyza”(字母表左移一个字母)然后我使用像“hello”这样的消息时,我将得到输出“ijklmnopqrstuvwxyza”,它以正确的字母开头,但随后只是继续对我莫名其妙地解析字母表。即使我只写一个字母长的消息,密文也会打印为多个字符。
所以我的问题是:
我的假设是否正确,是否有一种方法可以不使用指针来完成这个挑战?如果是这样,我如何在不使用 & 或 * 的情况下更正这些错误消息?
当我使用 & 和 * 时,是什么导致了这种奇怪的尾随字母表行为?
谢谢。
您在 string cypherText[strlen(plainText)];
中定义了一个字符串数组,因此最初的错误是由于试图将一个字符串(也称为 char*)分配给一个字符串数组(也称为 char**),因此:
error: format specifies type 'char *' but the argument has type 'string *' (aka 'char **') [-Werror,-Wformat]
printf("%s\n", cypherText);
你什么时候做的
if(isupper(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'A'];
}
else if (islower(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'a'];
}
您正在操纵指针 cypherText 指向的位置,您实际上是在分配 cypherText[0][0] 从 &key[plainText[i] - 'a']
开始,在您的测试用例中是字母 'i'。 i 的每个增量都会更改 cypherText 数组的行,因此 cypherText[1][0] 将指向字母 'f'、,但重要的是它与分配给 [=] 的内存相同14=].
当你 printf("%s\n", *cypherText);
时,你要求打印一个字符串,而 *cypherText
是你的字符串数组的开始,所以程序很乐意打印出你之前的第一个字符串分配与 key
相同,但从字母 'i' 开始。它读取此字符串,直到到达“\0”并愉快地结束它。
挑战在于创建一个程序,您可以在其中输入一个 26 个字符长的字符串,基本上可以替换字母表。因此,例如,如果您将密钥设置为“qwertyuiopasdfghjklzxcvbnm”,它将使用 q 表示 a,w 表示 b,e 表示 c,r 表示 d,等等。然后您输入一个字符串作为您的消息,它将明文转换为密文。
到目前为止,在课程中我们还没有涉及指针,所以我想人们应该能够在不使用 * 或 & 来引用指针的情况下完成这一挑战。相反,我们被告知使用允许我们使用“字符串”的库,而库则处理在后台为我们使用指针的技术性工作。不过我对此有点困惑,因为我最初尝试的代码是这样的:
{
if(isupper(plainText[i]))
{
cypherText[i] = key[plainText[i] - 'A'];
}
else if (islower(plainText[i]))
{
cypherText[i] = key[plainText[i] - 'a'];
}
}
printf("%s\n", cypherText);
但我收到以下错误:
error: incompatible integer to pointer conversion assigning to 'string' (aka 'char *') from 'char'; take the address with & [-Werror,-Wint-conversion]
cypherText[i] = key[plainText[i] - 'A'];
^ ~~~~~~~~~~~~~~~~~~~~~~~
&
error: incompatible integer to pointer conversion assigning to 'string' (aka 'char *') from 'char'; take the address with & [-Werror,-Wint-conversion]
cypherText[i] = key[plainText[i] - 'a'];
^ ~~~~~~~~~~~~~~~~~~~~~~~
&
error: format specifies type 'char *' but the argument has type 'string *' (aka 'char **') [-Werror,-Wformat]
printf("%s\n", cypherText);
所以我把代码改成了下面的
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string key;
do
{
key = get_string("Key:");
}
while(strlen(key) != 26);
string plainText = get_string("Text:");
string cypherText[strlen(plainText)];
for (int i = 0; plainText[i] != '[=12=]'; i++)
{
if(isupper(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'A'];
}
else if (islower(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'a'];
}
}
printf("%s\n", *cypherText);
}
现在它编译了但没有按预期工作,而且这个错误不是我通过调试能够识别的。基本上当我 运行 使用键“bcdefghijklmnopqrstuvwxyza”(字母表左移一个字母)然后我使用像“hello”这样的消息时,我将得到输出“ijklmnopqrstuvwxyza”,它以正确的字母开头,但随后只是继续对我莫名其妙地解析字母表。即使我只写一个字母长的消息,密文也会打印为多个字符。
所以我的问题是:
我的假设是否正确,是否有一种方法可以不使用指针来完成这个挑战?如果是这样,我如何在不使用 & 或 * 的情况下更正这些错误消息?
当我使用 & 和 * 时,是什么导致了这种奇怪的尾随字母表行为?
谢谢。
您在 string cypherText[strlen(plainText)];
中定义了一个字符串数组,因此最初的错误是由于试图将一个字符串(也称为 char*)分配给一个字符串数组(也称为 char**),因此:
error: format specifies type 'char *' but the argument has type 'string *' (aka 'char **') [-Werror,-Wformat]
printf("%s\n", cypherText);
你什么时候做的
if(isupper(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'A'];
}
else if (islower(plainText[i]))
{
cypherText[i] = &key[plainText[i] - 'a'];
}
您正在操纵指针 cypherText 指向的位置,您实际上是在分配 cypherText[0][0] 从 &key[plainText[i] - 'a']
开始,在您的测试用例中是字母 'i'。 i 的每个增量都会更改 cypherText 数组的行,因此 cypherText[1][0] 将指向字母 'f'、,但重要的是它与分配给 [=] 的内存相同14=].
当你 printf("%s\n", *cypherText);
时,你要求打印一个字符串,而 *cypherText
是你的字符串数组的开始,所以程序很乐意打印出你之前的第一个字符串分配与 key
相同,但从字母 'i' 开始。它读取此字符串,直到到达“\0”并愉快地结束它。