arrays - CS50 pset2 替换
问题描述
挑战在于创建一个程序,您可以在其中输入一个 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] != '\0'; 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”,但至关重要的是,它与分配给key
.
当 you 时printf("%s\n", *cypherText);
,您要求打印一个字符串,并且*cypherText
是字符串数组的开头,因此程序会愉快地打印出第一个字符串,您之前将其分配为与 相同key
,但从字母 'i' 开始. 它读取这个字符串,直到到达 '\0' 并愉快地称之为一天。
推荐阅读
- excel - 带有嵌套 For 循环和 if 语句需要一段时间执行的简短 VBA 脚本
- ios - 随机放置不同大小的 UIImage
- javascript - 无法将复选框值传递给数据库
- mysql - MySql 复合外键 ON DELETE 设置 null
- nginx - 使用 HTTPS Web 服务在 Ingress 上获取 ERR_TOO_MANY_REDIRECTS
- osgi - 向 OpenDaylight 应用程序添加功能的过程
- splunk - 记录每天最早登录时间
- javascript - 保存私人数据;来自 Await Fetch 的非预期响应
- javascript - 如何使用 map 函数像数组一样使用我的对象
- node.js - 为什么 mocha 突然开始输出详细日志?