我一直在进行CS50X pset2替换。我认为这差不多完成了。当我输入 </div>
</div>
{% endfor %}
或A
B
等单个字符时,密文将得到正确的结果。 (例如D
将获得A
,“ B”将获得J
,而T
将获得D
,依此类推...
但是,如果我输入E
,则密文将仅显示ABC
,而其他密文则无法显示。我做错了什么?
J
答案 0 :(得分:0)
您的问题是逻辑错误,似乎是由于您试图对失控的代码进行更改而导致的。您的代码中有不必要的循环和未使用的变量。您需要更改u
声明的范围,以便在每次迭代时将其重新初始化。您只需要完全删除for (int i = 0, n = strlen(key); i < n; i++)
循环,就不使用i
或n
。 ciphertext
和l
(ell)也是如此。
您需要在int u = 64;
之后立即移动if (isupper(plaintext[k]))
,以便在每次迭代时将其重置。
我怀疑所有printf
语句都用于调试,而您实际上只想要key
输出。综上所述,您可以将代码重新排列为:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, string argv[]) {
if (argc == 2) { /* validate key given */
string key = argv[1];
string plaintext = get_string("plaintext: ");
printf("ciphertext: ");
for (int k = 0, p = strlen(plaintext); k < p; k++)
{
if (isupper(plaintext[k]))
{
int u = 64;
for (int j = 0; j < 26; j++)
{
u = u + 1;
if (u == plaintext[k]) {
printf("%c", key[j]);
break;
}
}
}
else
printf("%c", plaintext[k]);
}
putchar ('\n');
}
}
使用/输出示例
$ ./bin/cs50_cypher2 JTREKYAVOGDXPSNCUIZLFBMWHQ
plaintext: ABD
ciphertext: JTE
简化逻辑
如果考虑以上代码的实际作用,可以将其简化为:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main (int argc, string argv[]) {
if (argc < 2) { /* validate key given */
fputs ("usage: ./program key\n", stderr);
return 1;
}
string key = argv[1];
string plaintext = get_string("plaintext: ");
printf("ciphertext: ");
for (int k = 0, p = strlen(plaintext); k < p; k++)
{
if (isupper(plaintext[k]))
putchar (key[plaintext[k] - 'A']);
else
putchar (plaintext[k]);
}
putchar ('\n');
}
或者,如果您使用三元运算符,则for
循环会简化为:
for (int k = 0, p = strlen(plaintext); k < p; k++)
putchar (isupper(plaintext[k]) ? key[plaintext[k] - 'A'] : plaintext[k]);
并且由于不需要调用strlen(plaintext)
,因此您可以完全消除string.h
,而只需循环for (int k = 0; plaintext[k]; k++)
,因为plaintext
是一个以Null结尾的字符串,因此整个程序可以减少为:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
int main (int argc, string argv[]) {
if (argc < 2) { /* validate key given */
fputs ("usage: ./program key\n", stderr);
return 1;
}
string key = argv[1];
string plaintext = get_string("plaintext : ");
printf("ciphertext: ");
for (int k = 0; plaintext[k]; k++)
putchar (isupper(plaintext[k]) ? key[plaintext[k] - 'A'] : plaintext[k]);
putchar ('\n');
}
处理小写字母
您知道作为第一个参数输入的key
都是大写的。因此,如果要输出小写的key
,则在应用偏移量后必须在键上调用tolower()
。由于对于大写字母,您只想知道要使用的26个字符的键中的偏移量,因此只需找出当前字母来自'A'
的字母数,然后在key[]
中获取该偏移量,例如
key[plaintext[k] - 'A']
对于小写输入,您需要找出key
中的偏移量以找出小写字母的差异,然后将tolower()
应用于键,例如
tolower(key[plaintext[k] - 'a'])
总而言之,您的for
循环可以写为:
for (int k = 0; plaintext[k]; k++) {
if (isupper(plaintext[k]))
putchar (key[plaintext[k] - 'A']);
else if (islower(plaintext[k]))
putchar (tolower(key[plaintext[k] - 'a']));
else
putchar (plaintext[k]);
}
使用/输出示例
$ ./bin/cs50_cypher4 JTREKYAVOGDXPSNCUIZLFBMWHQ
plaintext : AbZ 50
ciphertext: JtQ 50
仔细检查一下,如果还有其他问题,请告诉我。
答案 1 :(得分:0)
我也尝试检测低调,但是结果不是我想要的。我输入“ AbZ 50”。假设答案是“ JtQ 50”。但是,它是“ JTQ 50”
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, string argv[]) {
if (argc == 2) { /* validate key given */
string key = argv[1];
string plaintext = get_string("plaintext: ");
printf("ciphertext: ");
for (int k = 0, p = strlen(plaintext); k < p; k++)
{
if (isupper(plaintext[k]))
{
int u = 64;
for (int j = 0; j < 26; j++)
{
u = u + 1;
if (u == plaintext[k]) {
printf("%c", key[j]);
break;
}
}
}
else if (islower(plaintext[k]))
{
int l = 96;
for (int j = 0; j < 26; j++)
{
l = l + 1;
if (l == plaintext[k]) {
printf("%c", key[j]);
break;
}
}
}
else
printf("%c", plaintext[k]);
}
putchar ('\n');
}
}