【发布时间】:2022-01-15 21:41:53
【问题描述】:
代码如下:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[])
{
string key = argv[1];
string keyupper = argv[1];
string keylower = argv[1];
if (argc != 2) //makes sure there is exactly 2 arguments (the program executable and the key)
{
printf("Please input a key.\n");
return 1;
}
else if (strlen(key) != 26) //makes sure the key is exactly 26 letters
{
printf("Please make sure the key is 26 unique letters.\n");
return 1;
}
for (int i = 0; i < 26; i++) //the loop to make the uppercase key
{
keyupper[i] = toupper(keyupper[i]);
}
for (int i = 0; i < 26; i++) //the loop to make the lowercase key
{
keylower[i] = tolower(keylower[i]);
}
本质上,我想使用在执行程序时输入的密钥进行非常基本的加密,它需要包含 26 个唯一字母。我想创建两个数组,一个大写和一个小写,以使其他一切对我来说更容易,但是在运行此代码时,所有键都变为大写或小写,具体取决于最后创建的循环(在这种情况下,它们都是变成小写)。即使key 被更改为小写,即使它只用作声明一次。除了这个,其他一切都有效。
这是针对 CS50 课程的,因此库中包含 toupper() 等函数。
这是我的第一个问题,如果措辞不当,非常抱歉。谢谢!
【问题讨论】:
-
它们不是不相关的字符串:三个变量都指向同一个字符串。
string key = argv[1];不会创建新字符串,只会创建指针的副本。例如,您需要string key = strdup(argv[1]); -
如果你查看
string的typedef,你会发现它是一个指针。它不包含它指向的数据的副本。所有的指针都指向同一个数据块。如果您需要数据的副本以便能够对其进行更改并保持原始数据不变,请制作副本。 -
谢谢大家!我想我已经尽可能地了解它了,现在我知道该怎么做了。
-
再一次,cs50 在 typedef 别名中隐藏基本指针类型(如
char *)的可怕尝试再次让毫无戒心的初学者陷入困境。如果所有这三个变量都是char *而不是string,并且main的参数包括char *argv[]而不是string argv[],那么问题会更加更加明显。指针在 C 中无处不在 使用,相信我,C 工程师希望看到那些*的。它是一面巨大的挥舞旗帜,宣布“这是指向某物的指针”。接受这一点,不要像 cs50 那样在别名中隐藏指针类型。 -
@Nizz 你没有正确理解。指针是一个变量。它是一个变量,其值为地址。正如
int保存整数,float保存浮点值,char保存字符值一样,指针也是如此;他们持有地址。int a; int *p = &a;声明了两个变量;一个intvar 和一个指向intvar 的指针。 cs50 的标头在别名string后面隐藏了一个指针类型,这使得 less 很明显,您的所有代码所做的只是将相同的 address 复制到三个不同的指针变量中,所有之后他们指向相同的数据。