【发布时间】:2023-03-08 15:20:01
【问题描述】:
我正在编写一个程序,它在命令提示符处接受一个字符串,然后将字符串的每个字符转换为相应的字母表中的 0-25 位。然后,每个数字用于加密用户在程序提示后输入的另一个字符串的每个字符。第二个字符串的每个字母字符应与整数字符串的顺序匹配,如果第二个字符串较长,整数字符串将换行。该程序的目标是使用第一个字符串作为键来移动消息的每个字符(第二个字符串)。
示例(期望的输出):
用户运行程序并输入关键字:bad
提示用户仅输入字母字符串和标点符号:Dr. Oz
程序将关键字 'bad' 转换为 1,0,3
程序将消息加密成Er. Ra
我实际得到的是:
… T.B.S. …
我已经尝试了很多事情,但不幸的是,我似乎无法弄清楚如何在不循环第二条消息的情况下循环和包装密钥。如果你运行程序,你会看到我的问题。
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int shift(char key1);
int main(int argc, string argv[]) // user enter number at cmd prompt
{
if (argv[1] == '\0')
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
string key = argv[1]; // declare second arg as string
for (int i = 0, n = strlen(key); i < n; i++)
if (isdigit(key[i]) != 0 || argc != 2)
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
string text = get_string("plaintext: ");
printf("ciphertext: ");
int k;
char t;
for (int j = 0, o = strlen(text); j < o; j++)
{
t = text[j];
for (int i = 0, n = strlen(key); i < n; i++)
{
k = shift(key[i]);
if (isupper(t))
{
t += k;
if (t > 'Z')
{
t -= 26;
}
}
if (islower(t))
{
t += k;
if (t > 'z')
{
t -= 26;
}
}
printf("%c", t);
}
}
printf("\n");
}
int shift(char key1)
{
int k1 = key1;
if (islower(key1))
{
k1 %= 97;
}
if (isupper(key1))
{
k1 %= 65;
}
return k1;
}
感谢任何帮助和建议,但请记住,解决方案应与我的程序建议的编码水平相匹配。编写这个程序可能有许多高级方法,但不幸的是,我们仍处于本课程的开始阶段,因此展示新方法(我一定会尝试理解)可能会让我头疼。
【问题讨论】:
-
如果您点击vigenere,您会发现很多与您的程序相似的程序。您也许可以在其中找到解决方案。
-
您的行
if (argv[1] =='\0')并非完全错误,但最好使用0或NULL编写——'\0'是一个非正统但有效的空指针常量。你不是在比较一个角色。您正在将字符指针与空指针进行比较。同样,下一个循环中的argc != 2测试并非完全错误,但由于它在循环中而不必要地重复,并且在初始测试中可能会更好:if (argc != 2 || argv[1] == NULL || argv[1][0] == '\0')(非空第一个参数的额外测试)。 -
您需要删除内循环的循环控制,但保留相当数量的内循环主体。您可以使用
j计算正确的键索引;您还将获得密钥的长度(称为keylen)。您将找到与j % keylen一起使用的键的正确元素(因此,对于 3 个字符的键,您将获得依次使用的值 0、1、2)。您在 shift 中的代码可以使用减法而不是模运算符——我以前没有见过这种方法,但我认为它确实有效,但它可能不如k1 -= 'a';或k1 -= 'A';干净。您的验证可能应该使用isalpha()进行检查。
标签: encryption cs50 vigenere