我在堆栈溢出上看到了类似的答案,但是没有一个问题和我一样。我使用这种简单的凯撒密码加密功能的问题是,对于我的加密数组的位置[2](并且仅在位置[2]),一个(^ 3)符号,然后在位置[3]处的加密字符串被连接到它。
void encryptIDS(char login_ids[5][6])
{
int i = 0;
int j = 0;
int stop = 0;
int alphabet_count = 0;
int numbers_count = 0;
char lower_case[27] = {'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'};
char numbers[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9'};
char encrypted_string[5][6];
for (j = 0; j < 5; j++)
{
for (i = 0; i < 5; i++)
{
alphabet_count = 0;
numbers_count = 0;
stop = 0;
while (stop == 0)
{
if (login_ids[j][i] == lower_case[alphabet_count])
{
encrypted_string[j][i] = ((((login_ids[j][i]-'a')+7)%26)+'a');
stop = 1;
}
else if (login_ids[j][i] == numbers[numbers_count])
{
encrypted_string[j][i] = ((((login_ids[j][i] - '0')+7)%10)+'0');
stop = 1;
}
else
{
alphabet_count++;
numbers_count++;
}
}
}
}
printf("debug : %s\n", encrypted_string[0]);
printf("debug : %s\n", encrypted_string[1]);
printf("debug : %s\n", encrypted_string[2]);
printf("debug : %s\n", encrypted_string[3]);
printf("debug : %s", encrypted_string[4]);
}
login_ids的内容为“ vc136”,“ jc580”,“ cl274”,“ tm361”,“ ns792” 当将它们打印出来时,除了麻烦的第三个“ cj803”,“ qj257”,“ js941 ^ 3at038”,“ at038”,“ uz469”外,它们都很好地加密了。 这是非常令人毛骨悚然的,因为位置[2]处的字符串有6个以上的字符,不应包含。 感谢所有反馈,包括对我的代码的糟糕程度的评论,或者此问题是否以任何方式滥用了网站。谢谢。
答案 0 :(得分:1)
别生气,但是您的代码令人怀疑:)
但是,这是一个学习原因以及如何解决它的机会,因此,我将详细解释int细节:
您的代码有四个主要问题。
其中两个中断程序,并导致其打印垃圾或由于分段错误而崩溃,具体取决于程序运行时的内存布局。
另外两个让您的程序打印出正确的答案,但是却浪费了内存和处理器周期,使效率极低。
如果这是一项作业的评分依据,您将失去分数,并且如果您正在自学,这将是不好的编程习惯。
问题1:
正如注释中已经指出的那样,您必须始终使用NULL将C中的字符串终止。
如果您不这样做,那么像printf
这样使用它们的函数将一直打印内存内容,直到遇到随机的NULL值或您的程序崩溃为止。
因此,在外部for
循环中,您必须添加如下一行:
for (j = 0; j < 5; i++) {
//code to do the cypher
encrypted_string[j][5] = '\0'; //add terminator to string
}
或者,您可以按照Bwebb显示的方式初始化数组:
encrypted_string[5][6] = { '\0' };
这将提前在所有数组单元中放入零。但是,如果使用此方法,请注意不要覆盖其中一个循环中字符串的最后一个单元格!
问题2:
Bwebb也指出,您可以同时增加alphabet_count
和numbers_count
,但是使用numbers_count
来索引较小的数组。
这意味着对于从k到z的任何字母,您的程序都将在执行第二次if
检查时访问它不应接触的内存。
但是,如果您解决以下两个问题并正确构造代码,则该问题将自行消失。
问题3:
您浪费了两个大数组:字母数组和数字数组。
您不需要它们!由于正确计算了密码,因此您必须已经知道计算机中字母和数字的表示方式,因此不需要将字符串与这些数组的内容一一比较。
您知道字母是一个连续范围,因此只需使用一个if
。
问题4:
您浪费了while
循环的时间。
这是问题3中所述相同问题的一部分-您无需循环!
只需进行一次比较以查看当前字符是否在字母范围内,否则就可以进行另一次比较以查看当前字符是否在数字范围内。
如果仅解决问题1和2,则您的代码将正常工作,但是如果解决3和4,您的代码将更短,更易于阅读和理解,因此出现其他错误的机会将大大减少。
这是操作方法:
//this is the inner loop, the outer loop over j stays the same
for (i = 0; i < 5; i++) {
//check if this is a letter - a range between a and z inclusive:
if (encrypted_string[j][i] >= 'a' && encrypted_string[j][i] <= 'z') {
encrypted_string[j][i] += 7; //encrypt through shift by 7
//rotate to beginning of alphabet if needed:
if (encrypted_string[j][i] > 'z') encrypted_string[j][i] -= 26;
} else if (/* do the same thing for numbers) {
...
}
}
请注意,我将您的加密计算分为两行:这也是为了使其易于阅读和理解。
您仍然可以使用原始计算:
encrypted_string[j][i] = ((((login_ids[j][i] - 'a') + 7) % 26) + 'a');
但是可读性是任何好的代码的重要方面。
答案 1 :(得分:0)
#include <stdio.h>
void encryptIDS(char login_ids[5][6]);
int main(void) {
char login_ids[5][6] = {{"vc136"},{"jc580"},{"cl274"},{"tm361"},{"ns792"}};
encryptIDS(login_ids);
return 0;
}
void encryptIDS(char login_ids[5][6])
{
int i = 0;
int j = 0;
int stop = 0;
int alphabet_count = 0;
int numbers_count = 0;
char lower_case[27] = {'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'};
char numbers[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9'};
char encrypted_string[5][6] = {0};
for (j = 0; j < 5; j++)
{
for (i = 0; i < 5; i++)
{
alphabet_count = 0;
numbers_count = 0;
stop = 0;
while (stop == 0)
{
if (login_ids[j][i] == lower_case[alphabet_count])
{
encrypted_string[j][i] = ((((login_ids[j][i]-'a')+7)%26)+'a');
stop = 1;
}
if(numbers_count < 10)
{
if (login_ids[j][i] == numbers[numbers_count])
{
encrypted_string[j][i] = ((((login_ids[j][i] - '0')+7)%10)+'0');
stop = 1;
}
}
alphabet_count++;
numbers_count++;
}
}
}
printf("debug : %s\n", encrypted_string[0]);
printf("debug : %s\n", encrypted_string[1]);
printf("debug : %s\n", encrypted_string[2]);
printf("debug : %s\n", encrypted_string[3]);
printf("debug : %s", encrypted_string[4]);
}
输出
debug : cj803
debug : qj257
debug : js941
debug : at038
debug : uz469
问题在于数字索引,当字母花了十多次迭代才能找到匹配项时。我重新安排了while循环逻辑以防止超出范围的索引,这是您期望的结果吗?
编辑,我将您的代码复制/粘贴到了codechef.com/ide中以进行修复,但是我没有解决所有的格式/缩进问题。在下一次发布之前,您应该自行修复格式(对于回答您的人只是一个FYI)。