/*宏定义*/
#define _CRT_SECURE_NO_WARNINGS
/*头文件*/
#include<stdio.h>
#include<stdlib.h>
/*函数声明*/
void clearInputBuffer(); // 输入缓冲区清除函数的声明
int Str_Num_Judgement(int l, char* str); // 字符串字符数判断函数声明
/*外函数部分(自定义函数部分)*/
void clearInputBuffer() { // 用于清除缓冲区当中多余字符的函数工具
int c;
while ((c = getchar()) != '\n') {};
};
int Str_Num_Judgement(int l, char* str) { // 字符串判断函数
while (1) {
if (l > 98) {
printf("您输入的字符个数已经超过了溢出保护限制的字符数98个字符,请您重新输入\n");
clearInputBuffer(); // 清空输入缓冲区当中的字符
for (int i = 0; i < 100; i++) {
str[i] = '\0'; // 若超出了字符个数要求则全部进行空字符初始化
};
fgets(str, sizeof(str), stdin); // 重新输入需要加密的明文字符串
}
else
return 0; // 判断结束(由于输入字符数满足相应要求)
}; // 反复执行判断,直到字符数满足<=98字符即可执行下一个程序
};
/*主函数部分*/
int main() { // 8.3.5字符串加密与解密
int k = 0;
int command_num = 0; // 主程序命令符参量
char mw_str[100] = { 0 }; // 需要进行加密操作的明文
printf("请输入要加密的明文:\n");
fgets(mw_str, sizeof(mw_str), stdin); // 输入明文(其输入的非回车符的字符数不能超过98字符)
k = strlen(mw_str) - 1;
Str_Num_Judgement(k, mw_str); // 调用字符串判断函数(当字符个数满足<=98时,则该函数执行完毕)
printf("加密后的密文是:\n");
for (int i = 0; i <= strlen(mw_str) - 2; i++) { // 对明文进行加密
printf("%c", mw_str[i] + i + 5); // 加密之后并输出
}
printf("\n");
while (1) {
printf("输入1加密新的明文,输入2对刚加密的密文进行解密,输入3退出系统:\n");
printf("请输入命令符:\n");
scanf("%d", &command_num); // 请输入命令符(1、2、3)
clearInputBuffer(); // 清除输入缓冲区字符
switch (command_num) {
case 1: // 加密新的明文
for (int i = 0; i < sizeof(mw_str); i++) {
mw_str[i]='\0';// 将明文顺序表(明文字符数组和密文字符数组)初始化
};
printf("请输入要加密的明文:\n");
fgets(mw_str, sizeof(mw_str), stdin); // 输入明文(其输入的非回车符的字符数不能超过98字符)
Str_Num_Judgement(k, mw_str); // 调用字符串判断函数(当字符个数满足<=98时,则该函数执行完毕)
printf("加密后的密文是:\n");
for (int i = 0; i <= strlen(mw_str) - 2; i++) { // 对明文进行加密
printf("%c", mw_str[i] + i + 5); // 加密之后并输出
}
printf("\n");
break;
case 2: // 对刚加密的明文进行解密
printf("解密后的明文是:");
for (int i = 0; i < strlen(mw_str); i++)
printf("%c",mw_str[i]);
break;
case 3: // 系统结束
return 0;
}
}
}
遇到了问题,具体问题是:
1.在执行fgets函数时即第一次执行调用Str_Num_Judgement函数之前,我输入的字符是超过了98字符,输入完后按下回车之后,程序没有给我执行Str_Num_Judgement函数当中if条件判断里的printf("您输入的字符个数已经超过了溢出保护限制的字符数98个字符,请您重新输入\n");
对于这个Str_Num_Judgement函数当中if条件判断语句中printf函数之后的代码不知道有没有执行?
2.程序执行时莫名其妙还把:
输入1加密新的明文,输入2对刚加密的密文进行解密,输入3退出系统:
请输入命令符:
执行了两次,不清楚是怎么一回事?
3.关于我的溢出保护机制的函数Str_Num_Judgement是完全没有起到作用吗?
具体的程序运行状况如下:
请输入要加密的明文:
iudshafdsaesaidlsaudsasdhhdsafuidshafjudsaifhdsuiahfdsfhdkhsafudsuafuidsafilujdsahfjhdsafjkahdsfuihdskjlfhlskdjfhlkfh
加密后的密文是:
n{k{qkqp€ot價{w€坵寍寋巰厗儞倛槏墮弶彅爯爮槚櫀Ι灄煘澀·々Сⅷ辅富ó境讣萍非毒铰辆谓萌柿善质谙
输入1加密新的明文,输入2对刚加密的密文进行解密,输入3退出系统:
请输入命令符:
输入1加密新的明文,输入2对刚加密的密文进行解密,输入3退出系统:
请输入命令符:
int Str_Num_Judgement(int l, char* str) 函数里是死循环,进去就回不来了。
问题1:因为字符串读入用fgets()函数,能读取的字符串最大长度为sizeof(mw_str) -1 ,即 100 - 1 = 99 ,当输入的字符串长度超过这个值时,它也只截取前99个,用 strlen(mw_str) 得到的值也为 99, 所以 k = strlen(mw_str) - 1; ,这里 k = 98 , 把 k 传递给 int Str_Num_Judgement()函数形参 l = 98 , if (l > 98) 这个条件不会满足,所以 条件判断语句中printf函数之后的代码不会被执行。
问题2:因为前面读取字符串的过程中,有像回车换行符 等多余的字符残留在输入缓冲区里,调用执行 Str_Num_Judgement(k, mw_str); 函数时,输入缓冲区清除函数 clearInputBuffer(); 未被执行到,所以进入 while(1) 循环时,出现了误动作。
问题3:上面问题1的原因,溢出保护机制的函数Str_Num_Judgement()是没有起到作用。
@ada 请回答下这个问题
你在 保护函数里的 sizeof 不能那样用 数组在作为参数进入被调用函数中会退化为一级指针。
也就是 Str_Num_Judgement 里 sizeof Str 要么是 4 要么是 8 取决于你是x86 还是 x64的应用,不会get更多的字符
fgets 正常情况下输入 n-1个字符 或遇到 换行符会结束。应该无法输入到 超过 99个字符
你不如在 main函数里写个do while
do{
memset(str,100, '\0');
fgets(str, sizeof(str)-1, stdin);
}
while (strlen(str) > 98);
这样预防溢出