我在提交该文件时遇到了麻烦,我的代码没有问题,在我对其进行测试时可以正常工作,但是由于某种原因,我不知道何时使用check50,它会返回以下结果:
:) 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
这个结果意味着我的代码输出了错误的结果,但是当我自己测试按键并输入文本时,它可以按预期的方式工作,我花了数小时试图弄清楚它,但是我不知道这是我的代码:
#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-替代),则您忽略了所需的简单输出
如果用户没有提供有效的密钥怎么办?
$ ./substitution ABC
Key must contain 26 characters.
还是真的不合作?
$ ./substitution
Usage: ./substitution key
您无法在每种情况下提供正确的输出。
现在,如注释中@EugeneSh所指出的,您的代码有些粗糙。您contains()
有点笨拙和多余。相反,您需要的是一个简单的频率阵列。一个由26个整数组成的数组,所有初始化为零,在其中您将键中的字符映射为0-25(通过转换chartolower()
并减去'a'
soa-z
映射为0-25
。然后对于中的每个字符key
,您只需检查array[tolower(key[i]) - 'a']
它是否是重复的char并返回false
如果没有,增量该元素,并检查下一个字符,例如:
#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[]
阵列用于这一目的。
您的cypher()
函数应该真正返回类型,string
以便密文对调用函数可用,而不仅仅是输出。(这不是错误,只是实际考虑)。您可以将cypher()
函数(重命名为encipher()
)重写并简化为:
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;
}
这些实际上只是所需的两个功能。如果完全放在一起,您将拥有:
#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()
已更新为单独cipher
分配以分配plain
(+1
用于n终止字符)中的字符数,并更改了输出提示(例如"plaintext "
和"ciphertext: "
根据问题),并添加#include <stdlib.h>
了默认情况下不包含在在线ide.cs50.io
CS50 IDE中的输出提示)
尝试一下,让我知道您是否有问题或需要其他帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句