CS50x-PSET2-替代 [英] CS50x - PSET2- Substitution
问题描述
我在提交该文件时遇到了麻烦,我的代码没有问题,在我对其进行测试时可以正常工作,但是由于某种原因,我不知道何时使用check50,它会返回以下结果:>
I am having troubles with this submission, I don't see a problem with my code and it works fine when I test it but for some reason I don't know when I use check50, it returns this result:
:) substitution.c exists
:) substitution.c compiles
:( encrypts "A" as "Z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
Cause
output not valid ASCII text
:( encrypts "a" as "z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key
Cause
output not valid ASCII text
:( encrypts "ABC" as "NJQ" using NJQSUYBRXMOPFTHZVAWCGILKED as key
Cause
expected "ciphertext: NJ...", not ""
:( encrypts "XyZ" as "KeD" using NJQSUYBRXMOPFTHZVAWCGILKED as key
Cause
expected "ciphertext: Ke...", not ""
:( encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZTEOGXHCIPJSQD as key
Cause
expected "ciphertext: Cb...", not ""
:) encrypts "This is CS50" as "Cbah ah KH50" using yukfrnlbavmwzteogxhcipjsqd as key
:( encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZteogxhcipjsqd as key
Cause
expected "ciphertext: Cb...", not ""
:( encrypts all alphabetic characters using DWUSXNPQKEGCZFJBTLYROHIAVM as key
Cause
expected "ciphertext: Rq...", not ""
:) handles lack of key
:) handles invalid key length
:) handles invalid characters in key
:) handles duplicate characters in key
:) handles multiple duplicate characters in key
这个结果意味着我的代码输出了错误的结果,但是当我自己测试键并输入文本时,它可以按预期的方式工作,我花了数小时试图弄清楚它,但是我不知道这是我的代码:
This results mean that my code outputs the wrong result but when I test the keys and input text myself , it works as it is supposed to, I spent hours trying to figure it out but I am clueless here is my code :
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
bool contains(char c, char arr[], int n)
{
for(int i = 0 ;i < n; i++)
{
if(c == arr[i])
{
return true;
}
}
return false;
}
bool validkey(string key)
{
if (strlen(key) != 26 )
{
return false;
}
char l[26];
for (int i = 0; i < 26; i++)
{
if(isalpha(key[i]))
{
if(contains(key[i],l,i))
{
return false;
}
else
{
l[i] = key[i];
}
}
else
{
return false;
}
}
return true;
}
void cypher(string key, string s)
{
int n = strlen(s);
char r[n+1];
char t;
char a = 'a';
int pos = 0;
char w;
for(int i = 0; i < n; i++)
{
if(isalpha(s[i])){
t = tolower(s[i]);
pos = t - a;
if (islower(s[i]))
{
r[i]= tolower(key[pos]);
}
else if (isupper(s[i]))
{
r[i] = toupper(key[pos]);
}
}
else
{
r[i] = s[i];
}
}
r[n]='\0';
printf("ciphertext: %s\n",r);
}
int main(int argc, string argv[])
{
if(argc != 2)
{
return 1;
}
string key = argv[1];
if(!validkey(key))
{
printf("Invalid");
return 1;
}
string q = get_string("plain text: ");
cypher(key,q);
return 0;
}
推荐答案
您的实际问题似乎是,如果没有提供输入或提供了无效的密钥(例如,来自 Pset2-替代
Your actual problem looks to be the fact that you have overlooked the simple output required if no-input is provided, or if an invalid key is provided, e.g. from Pset2 - Substitution
如果用户没有提供有效的密钥怎么办?
And what if a user doesn’t provide a valid key?
$ ./substitution ABC
Key must contain 26 characters.
还是真的不合作?
$ ./substitution
Usage: ./substitution key
在每种情况下您都无法提供正确的输出.
You fail to provide the correct output in each circumstance.
现在,如注释中的 @EugeneSh 所指出的那样,您的代码有些粗糙.您的 contains()
有点笨拙和多余.相反,您需要的是一个简单的频率阵列.由26个整数组成的数组,将其全部初始化为零,在此您将键中的字符映射为0-25(通过转换char tolower()
并减去'a'
, az
映射到 0-25
.然后对于 key
中的每个字符,您只需检查 array [tolower(key [i])-'a']
,则它是重复的char并返回 false
.如果不是,则递增该元素并检查下一个char,例如:
Now your code is a bit rough as pointed out by @EugeneSh in the comments. Your contains()
is a bit awkward and superfluous. What you need instead is a simple frequency-array. An array of 26-integers, initialized all zero, where you map the characters in key from 0-25 (by converting the char tolower()
and subtracting 'a'
so a-z
maps to 0-25
. Then for each character in key
, you simply check if array[tolower(key[i]) - 'a']
then it is a duplicate char and return false
. If not, increment that element and check the next char, e.g.:
#define KEYSZ 26
bool validkey (string key)
{
int keychk[KEYSZ] = {0};
if (strlen (key) != KEYSZ) {
return false;
}
for (int i = 0; key[i]; i++) {
int lowerk = tolower(key[i]) - 'a';
if (!isalpha (key[i]) || keychk[lowerk])
return false;
keychk[lowerk]++;
}
return true;
}
为此目的使用 keychk []
数组的地方.
Where the keychk[]
array is used for that purpose.
您的 cypher()
函数应该真正返回类型 string
,因此密文可用于调用函数,而不仅仅是输出.(这不是错误,只是实际考虑).您可以将 cypher()
函数(重命名为: encipher()
)重写为以下形式:
Your cypher()
function should really return type string
so the cipher text is available to the calling function, not simply output. (that isn't an error, just a practical consideration). You can rewrite and simplify your cypher()
function (renamed: encipher()
) as:
string encipher (string key, string s, string cipher)
{
int i = 0;
for (; s[i]; i++) {
if (isalpha (s[i])) {
int pos = tolower (s[i]) - 'a';
cipher[i] = islower(s[i]) ? tolower(key[pos]) : toupper(key[pos]);
}
else
cipher[i] = s[i];
}
cipher[i] = 0;
return cipher;
}
实际上,这只是所需的两个功能.如果完全放在一起,您将拥有:
Those are really the only two functions needed. If you put it altogether you would have:
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define KEYSZ 26
bool validkey (string key)
{
int keychk[KEYSZ] = {0};
if (strlen (key) != KEYSZ) {
return false;
}
for (int i = 0; key[i]; i++) {
int lowerk = tolower(key[i]) - 'a';
if (!isalpha (key[i]) || keychk[lowerk])
return false;
keychk[lowerk]++;
}
return true;
}
string encipher (string key, string s, string cipher)
{
int i = 0;
for (; s[i]; i++) {
if (isalpha (s[i])) {
int pos = tolower (s[i]) - 'a';
cipher[i] = islower(s[i]) ? tolower(key[pos]) : toupper(key[pos]);
}
else
cipher[i] = s[i];
}
cipher[i] = 0;
return cipher;
}
int main (int argc, string argv[])
{
if (argc < 2) {
fputs ("Usage: ./substitution key\n", stderr);
return 1;
}
size_t len = 0;
string key = argv[1];
if (!validkey (key)) {
fputs ("Key must contain 26 characters.\n", stderr);
return 1;
}
string plain = get_string ("plaintext: "), cipher;
len = strlen (plain);
cipher = malloc (len + 1);
printf ("ciphertext: %s\n", encipher (key, plain, cipher));
free (cipher);
return 0;
}
(注释: main()
已更新,可以分别分配密码
和 plain
(终止字符的字符为 +1
)并更改了输出提示,例如纯文本"
和"密文:"
根据问题,并添加了 #include< stdlib.h>
,默认情况下,该 #include< stdlib.h>
并不包含在在线 ide.cs50.io
中CS50 IDE)
(note: main()
updated to allocate separately for cipher
allocating for the number of characters in plain
(+1
for the nul-terminating character) and changed output prompts, e.g. "plaintext "
and "ciphertext: "
as per the problem, and added #include <stdlib.h>
which is not included by default with the online ide.cs50.io
CS50 IDE)
请尝试一下,让我知道您是否遇到问题或需要其他帮助.
Give that a try and let me know if you have problems or need additional help.
这篇关于CS50x-PSET2-替代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!