【发布时间】:2018-09-11 04:52:03
【问题描述】:
我已经为 cs50 中的 Vigenere 问题编写了这段代码。 但是,当我打印使用 58 和 90 而不是 65 和 97 的加密字母时,它并没有按预期工作。(A 和 a 的 ASCII 值)
这样做会给我想要的结果,但我不明白为什么会这样。减去“a”或“A”时,它给了我错误的加密文本,这对我来说没有任何意义。
我查找了一些不同的解决方案,它们都用 'a' 或 'A' 减去以获得字母索引,但是这样做对我不起作用。
我真的不明白为什么我必须在我的代码中使用这些值也许任何人都可以帮助我了解哪里出了问题或我的逻辑错误在哪里。
提前致谢。
编辑:我改变了
k[z] = tolow(k[z]); to k[z] = toupper(k[z] - 'A');
我也变了
printf("%c",(((p[j]- 58) + k[l % strlen(k)]) % 26) + 'A'); to printf("%c",(((p[j]- 'A' -6) + k[l % strlen(k)]) % 26) + 'A');
-6 是因为这给了我正确的输出,这意味着某些东西仍然关闭
关键:培根
明文:上午十一点在公园见我
预期输出:Negh zf av huf pcfx bt gzrwep oz
-6 的实际输出:Negh zf av huf pcfx bt gzrwep oz
没有-6的实际输出:Tkmn fl gb nal vild hz mfxckv uf
不知何故,所有值都偏离了 -6,我不知道为什么
k.size() 也给了我错误,所以我保留了 strlen()。
int main(int argc,string argv[])
{
//checks if only one argument was typed
if (argc != 2)
{
printf("Error");
return 1;
}
//assigns the keyword argv[1] to k
string k = argv[argc -1];
//check if key is alphabetical only
for (int i = 0 , n = strlen(k); i < n; i++)
{
if(!isalpha(k[i]))
{
printf("Key is not alphabetical");
return 1;
}
}
printf("Key Valid\n");
//convert key to lowercase only
for(int z = 0; k[z]; z++)
{
k[z] = tolower(k[z]);
}
string p = get_string("Plaintext: ");
//iterate over p
//l is incremented only when the char is alphabetical and is used as index for k
for (int j = 0,l = 0 , o = strlen(p);j < o ;j++)
{
if(isalpha(p[j]))
{
if(isupper(p[j]))
{
//print enciphered letter
printf("%c",(((p[j]- 58) + k[l % strlen(k)]) % 26) + 'A');
}
else if(islower(p[j]))
{
//print enciphered letter
printf("%c",(((p[j]- 90) + k[l % strlen(k)]) % 26 ) + 'a');
}
//increment so that next char in k is used
l++;
}
else
{
//print unchanged
printf("%c",p[j]);
}
}
return 0;
}
【问题讨论】:
-
如果你转换输入键
toupper而不是tolower会发生什么?大写在历史上是一种默认设置(旧的 FORTRAN 代码全部大写),因此字母通常被规范化为大写而不是小写。但是对于字母 A,key 实际上应该具有值 0,因此转换实际上应该是toupper(k[z]) - 'A',然后应该不涉及任何魔术常量。 -
get_string函数是什么?你的输入是什么?你的预期输出是什么?你的实际输出是多少? -
继续我的第一条评论,如果你使用
- 'A'部分那么你不能使用strlen(k)并且必须使用k.size(),因为值零可以是字符串的一部分并且strlen认为值零作为字符串终止符,但string::size()没有。 -
我改变了 k[z] = tolower(k[z]);到 k[z] = toupper(k[z] - 'A');我也改变了 printf("%c",(((p[j]- 58) + k[l % strlen(k)]) % 26) + 'A');到 printf("%c",(((p[j]- 'A' -6) + k[l % strlen(k)]) % 26) + 'A'); -6 是因为这给了我正确的输出,这意味着有些东西仍然关闭我将在描述中指定输入和输出
-
另外@RetiredNinja get_string 函数会提示用户输入一个字符串,我认为cs50在2018年新课程中用get_string()“替换”了GetString()。正如我所说,我现在在描述中指定了所有输出和输入