正在做CS50的第2周。它应该是一个加密算法。我已经到了它对我的代码进行加密的地步,但由于某种原因,当我尝试测试我的代码并使用我的名字时,它不会使我的第二个 A 字符成为小写的 a。
密钥:NQXPOMAFTRHLZGECYJIUWSKDVB 输入:阿曼多
我得到的-->密文:NjzNgpe 我想要的-->密文:Njzngpe
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
char alpha[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int cypher[] = {};
char new[] = {};
void cypher_s(string k);
void scramble(string s, int l);
int main(int argc, string argv[])
{
if (argc == 2)
{
string key = argv[1];
cypher_s(key);
string text = get_string("plaintext: ");
scramble(text, strlen(key));
}
else
{
printf("You suck, you need a command line argument or typed too many\n");
return 1;
}
}
void cypher_s(string k)
{
for (int i = 0; i < strlen(k); i++)
{
cypher[i] = k[i];
}
}
void scramble(string s, int l)
{
for (int i = 0; i < strlen(s); i++)
{
int position = 0;
for (int k = 0; k < l; k++)
{
if (s[i] == alpha[position])
{
printf("Capital %c\n", s[i]);
new[i] = cypher[position];
position++;
}
else if (s[i] == tolower(alpha[position]))
{
printf("Lower %c\n", s[i]);
new[i] = tolower(cypher[position]);
position++;
}
else
{
position++;
}
}
}
printf("ciphertext: ");
for (int j = 0; j < strlen(new); j++)
{
printf("%c", new[j]);
}
printf("\n");
}
尝试您的代码,首先注意到的是尝试编译代码时返回的编译器警告,表示可能超出字符数组的边界。
/home/craig/C_Programs/Console/Crypto/main.c||In function ‘cypher_s’:|
/home/craig/C_Programs/Console/Crypto/main.c|36|warning: array subscript i is outside array bounds of ‘int[0]’ [-Warray-bounds]|
/home/craig/C_Programs/Console/Crypto/main.c|7|note: while referencing ‘cypher’|
/home/craig/C_Programs/Console/Crypto/main.c||In function ‘scramble’:|
/home/craig/C_Programs/Console/Crypto/main.c|68|warning: array subscript j is outside array bounds of ‘char[0]’ [-Warray-bounds]|
/home/craig/C_Programs/Console/Crypto/main.c|8|note: while referencing ‘new’|
/home/craig/C_Programs/Console/Crypto/main.c|56|warning: array subscript i is outside array bounds of ‘char[0]’ [-Warray-bounds]|
/home/craig/C_Programs/Console/Crypto/main.c|8|note: while referencing ‘new’|
/home/craig/C_Programs/Console/Crypto/main.c|50|warning: array subscript position is outside array bounds of ‘int[0]’ [-Warray-bounds]|
/home/craig/C_Programs/Console/Crypto/main.c|7|note: while referencing ‘cypher’|
/home/craig/C_Programs/Console/Crypto/main.c|50|warning: array subscript i is outside array bounds of ‘char[0]’ [-Warray-bounds]|
/home/craig/C_Programs/Console/Crypto/main.c|8|note: while referencing ‘new’|
||=== Build finished: 0 error(s), 6 warning(s) (0 minute(s), 0 second(s)) ===|
此外,即使全局变量是绝对允许的,但通常和习惯上使用每个函数的本地变量以避免变量引用的范围问题。
考虑到这一点并查看简化代码的建议,以下是代码的重构版本。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 100
void scramble(char * s, char * x, char * c);
int main(int argc, char * argv[])
{
if (argc == 2)
{
char * key = argv[1];
char text[SIZE], cypher[SIZE]; /* Define strings with a specific size in lieu of a zero length */
//cypher_s(key);
printf("plaintext: "); /* Do not have CS50 - using usual and customary printf/prompt method */
scanf("%s", text);
//string text = get_string("plaintext: ");
scramble(text, key, cypher);
printf("The scrambled text is: %s\n", cypher); /* Placed the output of the encrypted text in the main function */
}
else
{
printf("Please enter the encryption key as a parameter\n");
return 1;
}
}
void scramble(char * s, char * x, char * c)
{
char alpha[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int l = strlen(s); /* Length of the text to be encrypted */
int m = strlen(x); /* Length of the key */
strcpy(c, s); /* Set the target string to the text */
for (int i = 0; i < l; i++)
{
for (int k = 0; k < m; k++) /* Scan through the encryption key for match */
{
if (s[i] == alpha[k]) /* No need for a separate index counter */
{
//printf("Capital %c\n", s[i]);
c[i] = x[k];
break;
}
else if (s[i] == tolower(alpha[k]))
{
//printf("Lower %c\n", s[i]);
c[i] = tolower(x[k]);
break;
}
else
{
/* Not a character that needs to be encrypted */
}
}
}
}
以下是一些要点。
以下是使用此重构代码在终端进行的一些测试。
craig@Vera:~/C_Programs/Console/Crypto/bin/Release$ ./Crypto NQXPOMAFTRHLZGECYJIUWSKDVB
plaintext: Armando
The scrambled text is: Njzngpe
craig@Vera:~/C_Programs/Console/Crypto/bin/Release$ ./Crypto NQXPOMAFTRHLZGECYJIUWSKDVB
plaintext: Armando$%6__x
The scrambled text is: Njzngpe$%6__d
craig@Vera:~/C_Programs/Console/Crypto/bin/Release$
这些重构只是您遇到的问题的众多可能解决方案之一,但此代码重构的关键要点是: