为什么我的vigenere.c不工作?
我一直在修改代码的循环部分,我的check50总是失败。我不知道发生了什么事。下面是我的代码:为什么我的vigenere.c不工作?,c,encryption,cs50,vigenere,C,Encryption,Cs50,Vigenere,我一直在修改代码的循环部分,我的check50总是失败。我不知道发生了什么事。下面是我的代码: #include <stdio.h> #include <ctype.h> #include <cs50.h> #include <stdlib.h> #include <string.h> int main(int argc, string argv[]) { // declare variables int cipher
#include <stdio.h>
#include <ctype.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv[])
{
// declare variables
int cipherText;
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
printf("\n");
return 1;
}
// keyword is the second command line argument
string key = argv[1];
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if ((key[i] >= '0') && (key[i] <= '9'))
{
printf("Keyword must consist only of letters.");
return 1;
}
}
// get the plaintext
string plainText = GetString();
// encypher - iterate over the characters in string, print each one encrypted
for (int i = 0, j = 0, n = strlen(plainText); i < n; i++, j++)
{
// start the key again if key shorter than plainText
if (j >= strlen(key))
{
j = 0;
}
// skip key[j] if plainText[i] is not an alpha character
if (!isalpha(plainText[i]))
{
j = (j-1);
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j%keylen])%26) + 'A';
printf("%c", cipherText);
}
else if (islower(plainText[i]))
{
cipherText = (plainText[i] - 'a');
cipherText = ((cipherText + key[j%keylen])%26 + 'a');
printf("%c", cipherText);
}
else
{
printf("%c", plainText[i]);
}
}
printf("\n");
return 0;
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符串argv[])
{
//声明变量
密文;
如果(argc!=2)
{
printf(“用法:./vigenere关键字”);
printf(“\n”);
返回1;
}
//关键字是第二个命令行参数
字符串键=argv[1];
int-keylen=strlen(argv[1]);
//遍历关键字以检查是否按字母顺序排列
对于(inti=0,n=strlen(argv[1]);i='0')&&(键[i]=strlen(键))
{
j=0;
}
//如果明文[i]不是字母字符,则跳过键[j]
if(!isalpha(明文[i]))
{
j=(j-1);
}
//使大写字母Aa=0,Zz=25
如果(isupper(键[j]))
{
键[j]=(键[j]-“A”);
}
//使Aa=0,Zz=25表示小写字母
否则,如果(islower(图例[j]))
{
键[j]=(键[j]-“a”);
}
if(isupper(明文[i]))
{
密文=(明文[i]-“A”);
密文=((密文+密钥[j%keylen])%26)+'A';
printf(“%c”,密文);
}
else if(islower(纯文本[i]))
{
密文=(明文[i]-“a”);
密文=((密文+密钥[j%keylen])%26+'a');
printf(“%c”,密文);
}
其他的
{
printf(“%c”,明文[i]);
}
}
printf(“\n”);
返回0;
}
一些人回答说:“第一个for循环有问题。条件是检查i>keylen
,而它应该检查i
”
此外,在计算下一个输出值时,步骤应为
- (p[i]-65)产生一个介于0和25之间的数字
- 添加(键[i%keylen])会产生一个介于0和50之间的数字
- 应用模26,使数字介于0和25之间(这是缺少的步骤)
- 然后添加65以获得输出“
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0, n = strlen(argv[1]); i < n; i++)
{
if ((key[i] >= '0') && (key[i] <= '9'))
{
printf("Keyword must consist only of letters.");
return 1;
}
}
您可以对其进行优化,这样它就不会尝试使用%c
打印不可打印的字符,但这是朝着正确方向迈出的一大步
您确实不需要在循环中设置n
;您只需在循环之前设置keylen
,就可以编写:
for (int i = 0; i < keylen; i++)
您在每次迭代时通过键修改键字符串。但是,不幸的是,如果键中的任何字母是a
或a
,您已经将其转换为'\0'
,这意味着strlen(键)
返回与以前不同的答案。因此,您应该使用keylen
代替strlen()
.AFAICS,如果没有a
或a
,则该部分代码是正常的
稍后,您有:
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j%keylen])%26) + 'A';
printf("%c", cipherText);
}
j%keylen
是多余的;j
已被限制为0
。keylen-1
。与小写文本的代码类似
将这些更改放在一起,并使用fgets()
创建一个GetString()
函数,我得到:
#include <stdio.h>
#include <ctype.h>
// #include <cs50.h>
#include <stdlib.h>
#include <string.h>
typedef char *string;
static char *GetString(void)
{
static char buffer[4096];
if (fgets(buffer, sizeof(buffer), stdin) == 0)
{
fprintf(stderr, "EOF detected in GetString()\n");
exit(EXIT_SUCCESS);
}
buffer[strlen(buffer) - 1] = '\0';
return buffer;
}
int main(int argc, string argv[])
{
// declare variables
int cipherText;
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
printf("\n");
return 1;
}
// keyword is the second command line argument
string key = argv[1];
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0; i < keylen; i++)
{
if (!isalpha(key[i]))
{
printf("Keyword must consist only of letters (%c at %d)\n",
key[i], i+1);
return 1;
}
}
// get the plaintext
string plainText = GetString();
// encypher - iterate over the characters in string, print each one encrypted
for (int i = 0, j = 0, n = strlen(plainText); i < n; i++, j++)
{
// start the key again if key shorter than plainText
if (j >= keylen)
{
j = 0;
}
// skip key[j] if plainText[i] is not an alpha character
if (!isalpha(plainText[i]))
{
j = (j - 1);
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j]) % 26) + 'A';
printf("%c", cipherText);
}
else if (islower(plainText[i]))
{
cipherText = (plainText[i] - 'a');
cipherText = ((cipherText + key[j]) % 26 + 'a');
printf("%c", cipherText);
}
else
{
printf("%c", plainText[i]);
}
}
printf("\n");
return 0;
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j%keylen])%26) + 'A';
printf("%c", cipherText);
}
#include <stdio.h>
#include <ctype.h>
// #include <cs50.h>
#include <stdlib.h>
#include <string.h>
typedef char *string;
static char *GetString(void)
{
static char buffer[4096];
if (fgets(buffer, sizeof(buffer), stdin) == 0)
{
fprintf(stderr, "EOF detected in GetString()\n");
exit(EXIT_SUCCESS);
}
buffer[strlen(buffer) - 1] = '\0';
return buffer;
}
int main(int argc, string argv[])
{
// declare variables
int cipherText;
if (argc != 2)
{
printf("Usage: ./vigenere keyword");
printf("\n");
return 1;
}
// keyword is the second command line argument
string key = argv[1];
int keylen = strlen(argv[1]);
// iterate through keyword to check if alphabetical
for (int i = 0; i < keylen; i++)
{
if (!isalpha(key[i]))
{
printf("Keyword must consist only of letters (%c at %d)\n",
key[i], i+1);
return 1;
}
}
// get the plaintext
string plainText = GetString();
// encypher - iterate over the characters in string, print each one encrypted
for (int i = 0, j = 0, n = strlen(plainText); i < n; i++, j++)
{
// start the key again if key shorter than plainText
if (j >= keylen)
{
j = 0;
}
// skip key[j] if plainText[i] is not an alpha character
if (!isalpha(plainText[i]))
{
j = (j - 1);
}
// makes Aa = 0, Zz = 25 for the uppercase letters
if (isupper(key[j]))
{
key[j] = (key[j] - 'A');
}
// makes Aa = 0, Zz = 25 for lowercase letters
else if (islower(key[j]))
{
key[j] = (key[j] - 'a');
}
if (isupper(plainText[i]))
{
cipherText = (plainText[i] - 'A');
cipherText = ((cipherText + key[j]) % 26) + 'A';
printf("%c", cipherText);
}
else if (islower(plainText[i]))
{
cipherText = (plainText[i] - 'a');
cipherText = ((cipherText + key[j]) % 26 + 'a');
printf("%c", cipherText);
}
else
{
printf("%c", plainText[i]);
}
}
printf("\n");
return 0;
}
$ ./vigenere bakedalaska
What a wonderful world! The news is good, and the Vigenere cipher is solved.
Xhkx d wznvorguv arrwd! Lre oegw ls rogn, aod dlh Vtgwxese mmshpr ac splfig.
$