【发布时间】:2022-08-18 16:30:44
【问题描述】:
我在 cs50 上完成了凯撒任务,并在我的终端上对其进行了测试,它运行良好,但在 check50 上一直未能通过一些测试。
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
int getkey(string k);
string cipher(string s, int key);
int key;
int p;
int q;
int main(int argc, string argv[])
{
// Allow 2 command line inputs
if (argc == 2)
{
// Assign a local string to allow char scan
string s = argv[1];
// Check if all inputs are numbers
for (int i = 0; s[i] != 0; i++)
{
if (s[i] < 48 || s[i] > 57)
{
printf(\"Usage: ./caesar key\\n\");
return 1;
}
}
// Get key from string
int cipherkey = getkey(s);
// Get user text
string text = get_string(\"plaintext: \");
// Calculate ciphertext and print
string ciphertext = cipher(text, cipherkey);
printf(\"ciphertext: %s\\n\", ciphertext);
}
else
{
printf(\"Usage: ./caesar key\\n\");
return 1;
}
}
// Change string to int. Turns out theres already a function for this called atoi()
int getkey(string k)
{
key = 0;
for(int i = 0, conv = 0, n = strlen(k); k[i] != 0; i++, n--)
{
// Calcute the placevalue
p = pow(10, n-1);
conv = k[i] - 48; // Convert to int
key = key + (conv * p); // Sum up
}
return key % 26;
}
// Cipher text
string cipher (string s, int key)
{
for(int i = 0; s[i] != 0; i++)
{
if(islower(s[i]))
{
s[i] = s[i] + key;
while(s[i] > 122)
{
s[i] = (s[i] - 123) + 97;
}
}
else if(isupper(s[i]))
{
s[i] = s[i] + key;
while(s[i] > 90)
{
s[i] = (s[i] - 91) + 65;
}
}
}
return s;
}
带有错误信息
:) caesar.c compiles.
:) encrypts \"a\" as \"b\" using 1 as key
:( encrypts \"barfoo\" as \"yxocll\" using 23 as key
output not valid ASCII text
:) encrypts \"BARFOO\" as \"EDUIRR\" using 3 as key
:) encrypts \"BaRFoo\" as \"FeVJss\" using 4 as key
:) encrypts \"barfoo\" as \"onesbb\" using 65 as key
:( encrypts \"world, say hello!\" as \"iadxp, emk tqxxa!\" using 12 as key
output not valid ASCII text
:) handles lack of argv[1]
:) handles non-numeric key
:) handles too many arguments
我在不知道“atoi”函数的情况下编写了代码,所以我实现了一个名为 getkey() 的函数来返回密钥。当我正常返回密钥时,它失败了。
:( encrypts \"barfoo\" as \"onesbb\" using 65 as key
Output not a valid ASCII text
直到我返回 key % 26;
尽管该程序在我的终端上运行良好,但我不知道为什么 check50 不起作用。请帮忙。
更新代码:
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
string cipher(string s, int key);
int main(int argc, string argv[])
{
// Allow 2 command line inputs
if (argc == 2)
{
// Assign a local string to allow char scan
string s = argv[1];
// Check if all inputs are numbers
for (int i = 0; s[i] != 0; i++)
{
if (s[i] < 48 || s[i] > 57)
{
printf(\"Usage: ./caesar key\\n\");
return 1;
}
}
// Get key from string
int cipherkey = atoi(s);
// Get user text
string text = get_string(\"plaintext: \");
// Calculate ciphertext and print
string ciphertext = cipher(text, cipherkey);
printf(\"ciphertext: %s\\n\", ciphertext);
}
else
{
printf(\"Usage: ./caesar key\\n\");
return 1;
}
}
// Cipher text
string cipher (string s, int key)
{
for(int i = 0; s[i] != 0; i++)
{
if(islower(s[i]))
{
s[i] = (int) s[i] + key;
while(s[i] > \'z\')
{
s[i] = (s[i] - 123) + 97;
}
}
else if(isupper(s[i]))
{
s[i] = (int) s[i] + key;
while(s[i] > \'Z\')
{
s[i] = (s[i] - 91) + 65;
}
}
}
return s;
}
-
k[i] - 48你永远不应该使用这样的“幻数”。如果您指的是字符\'0\',则应使用\'0\'而不是某个数字。 -
如果您已经知道您的
getkey实现会导致问题,您可以删除所有其他代码并将此函数与您的测试用例一起发布。 -
如果
getkey函数旨在将字符串转换为数字,则添加%26没有任何意义。这似乎是您的加密机制的一些限制。然后在加密期间或解析该字符串后处理它。但是不要用这种不相关的功能污染该功能 -
除了指出
string隐藏了您正在处理signed chars的事实之外,没有时间研究您的密码函数...当您向(特别是)小写有符号字符添加值时,结果可能是负数数字...-127 to +1288 位签名...也许将char复制到int以便有足够的位保持正数并允许>按您的意愿工作... -
@Gerhardh 我已经摆脱了 getkey 函数并使用了 atoi(),我将一些幻数(如 90 和 122)更改为 \'z\' 和 \'Z\' 但它仍然返回错误消息