我似乎无法理解我的程序出了什么问题。作业是CS50在第2周的问题集中的“替代”。目标是创建一个程序,该程序在用户键入26个字符的键作为argv [2]后,将用户键入的文本转换为。用键切换常规字母。我的代码几乎可以正常工作,但是对于要加密的每个文本,使用一个或两个字母(每次都会更改),输出是错误的。
例如 ./substitution YUKFRNLBAVMWZteogxhcipjsqd
纯文本:这是CS50
密文:Cbah ah DH50
(其中字母C应该是K,而不是D)
甚至:
./ substitution NQXPOMAFTRHLZGECYJIUWSKDVB
纯文本:这是CS50
密文:Kfki ki DI50
(由于我的原因,我不知道字母T和字母i都是'k',而且都是错误的)
几个小时以来,我一直在拼命地寻找导致此错误的原因,但似乎找不到它。如果您能帮助我找到我,我将不胜感激。 预先感谢。
((如果您需要对输出进行进一步的说明,这是“ Check50”工具的消息:
:)替代存在。
:)替换。c编译
:(使用ZYXWVUTSRQPONMLKJIHGFEDCBA作为密钥,将“ A”加密为“ Z” 预期的“密文:Z ...”,而不是“密文:A ...”
:(使用ZYXWVUTSRQPONMLKJIHGFEDCBA作为密钥将“ a”加密为“ z” 预期的“密文:z ...”,而不是“密文:a ...”
:(使用NJQSUYBRXMOPFTHZVAWCGILKED作为密钥将“ ABC”加密为“ NJQ” 预期的“密文:NJ ...”,而不是“密文:CF ...”
:((使用NJQSUYBRXMOPFTHZVAWCGILKED作为密钥将“ XyZ”加密为“ KeD” 预期的“密文:Ke ...”,而不是“密文:Ke ...”
:(使用YUKFRNLBAVMWZTEOGXHCIPJSQD作为密钥,将“ This is CS50”加密为“ Cbah ah KH50” 预期的“密文:Cb ...”,而不是“密文:Cb ...”
:((使用yukfrnlbavmwzteogxhcipjsqd作为密钥,将“ This is CS50”加密为“ Cbah ah KH50” 预期的“密文:Cb ...”,而不是“密文:Cb ...”
:((使用YUKFRNLBAVMWZteogxhcipjsqd作为密钥将“ This is CS50”加密为“ Cbah ah KH50” 预期的“密文:Cb ...”,而不是“密文:Cb ...”
:(使用DWUSXNPQKEGCZFJBTLYROHIAVM作为密钥加密所有字母字符 预期的“密文:Rq ...”,而不是“密文:Rr ...”
:)处理缺少密钥的情况
:)处理无效的密钥长度
:)处理密钥中的无效字符
:)处理密钥中的重复字符
:)处理密钥中的多个重复字符)
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
// create the stirng variable alphabet for the key substitution
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int main(int argc, string argv[])
{
// get the key for the alphabet substitution as the second argument
string key = argv[1];
// if the user enters no key, instructions are given
if (argc == 1)
{
printf("Usage: ./substitution key\n");
return 1;
}
// loop to go through all the key chars and check them
for (int i = 0; i < 26; i++)
{
// if at least one of the chars is not a letter, print an error and return 1
if (!isalpha(key[i]))
{
printf("Key can contain only alphabetic characters.\n");
return 1;
break;
}
// adds another loop to confront a char with all the other 25 to see if there aare duplicates
for (int j = i + 1; j < 26; j++)
{
// if there is a repeated char, print an error and return 1
if (key[i] == key[j] || key[i] == ' ')
{
printf("Key doesn't allow repeating characters.\n");
return 1;
break;
}
}
}
// print an error and return 1 from main if the key is not 26 chats
if (strlen(key) != 26)
{
printf("Key must contain 26 characters.\n");
return 1;
}
else
{
// print 'plaintext: ', prompting the user for the string he wants to encrypt, using get_string
string pltxt = get_string("plaintext: ");
string cytxt = pltxt;
// get the lenght of the plaintext variable
int lentxt = strlen(pltxt);
// loop that goes through all the chars of the plaintext
for (int n = 0; n < lentxt; n++ )
{
// check if the char is a letter
if (isalpha(pltxt[n]))
{
// loop that goes through all the alphabet letters to see which one the current letter is and to change it with the keys one
for (int m = 0; m < 26; m++)
{
if (toupper(pltxt[n]) == alphabet[m])
{
// conditions that keep the cases of the substituted chars
if (islower(pltxt[n]))
{
pltxt[n] = tolower(key[m]);
}
else if (isupper(pltxt[n]))
{
pltxt[n] = toupper(key[m]);
}
}
}
}
// if char is not letter, let it as it is
else
{
cytxt[n] = pltxt[n];
}
}
// output 'cyphertext: ', followed by the encrypted string and a newline
printf("cyphertext: %s\n", cytxt);
// exit the program by returning 0 from main
return 0;
}
}
答案 0 :(得分:0)
循环中
for (int m = 0; m < 26; m++)
{
if (toupper(pltxt[n]) == alphabet[m])
{
// conditions that keep the cases of the substituted chars
if (islower(pltxt[n]))
{
pltxt[n] = tolower(key[m]);
}
else if (isupper(pltxt[n]))
{
pltxt[n] = toupper(key[m]);
}
}
}
可能会发生多次替换。
例如,在第一个示例中
./substitution YUKFRNLBAVMWZteogxhcipjsqd
plaintext: This is CS50
C
替换为K
K
替换为M
M
替换为Z
Z
替换为D
结果是C
被替换为D
。
为防止这种情况,您应该在第一次命中后退出循环,并且每个字符最多只能进行一次替换。
for (int m = 0; m < 26; m++)
{
if (toupper(pltxt[n]) == alphabet[m])
{
// conditions that keep the cases of the substituted chars
if (islower(pltxt[n]))
{
pltxt[n] = tolower(key[m]);
}
else if (isupper(pltxt[n]))
{
pltxt[n] = toupper(key[m]);
}
break; // add this
}
}