C语言多功能命令行工具加解密功能偶发不读取输入异常如何解决
问题根因
fflush(stdin)属于C标准未定义行为,仅部分编译器支持清空输入缓冲区的效果,跨环境甚至同环境多次运行都可能失效,残留的换行符会被后续的%c格式符、gets直接读取,导致跳过用户输入流程。- 代码中定义的
char *word、char *deWord均为未初始化的野指针,没有指向合法的内存空间,调用gets写入字符串时属于非法内存访问,行为完全随机,轻则运行异常直接退出,重则程序崩溃。 - 循环逻辑中
sizeof(ptr)获取的是指针变量本身的长度(32位系统为4字节、64位系统为8字节),而非字符串实际长度,仅能处理前4/8个字符,字符串长度超过该值时后续字符不会被加密/解密。 gets函数已被C11标准正式移除,不做输入长度校验,存在严重的缓冲区溢出漏洞。
修复后的完整代码
#include <stdio.h> #include <string.h> void encryptDecrypt(); // void checkPalindrome(); // void reverseWord(); // 替代fflush(stdin)的通用清输入缓冲区方案 void clearStdin() { int c; while ((c = getchar()) != '\n' && c != EOF); } int main() { int choice; printf("\nWelcome to Jeel's multi-feature C App\n\n"); printf("1. 字符串加密解密\t2. 回文检测\t3. 字符串翻转\n\n"); printf("请选择要使用的功能: "); scanf("%d", &choice); clearStdin(); // 清空scanf残留的换行符 switch (choice) { case 1: encryptDecrypt(); break; case 2: // checkPalindrome(); break; case 3: // reverseWord(); break; default: printf("输入选项无效!"); break; } return 0; } void encryptDecrypt() { char eOrD; printf("\n欢迎使用加密解密功能!\n\n"); printf("输入 'e' 加密字符串,输入 'd' 解密字符串 (e/d): "); scanf("%c", &eOrD); clearStdin(); if (eOrD == 'e' || eOrD == 'E') { // 定义固定长度的字符数组存储输入,替代野指针 char word[1024] = {0}; printf("\n请输入要加密的字符串: "); // 用fgets替代gets,限制输入长度避免溢出 fgets(word, sizeof(word), stdin); // 去掉fgets读取的末尾换行符 word[strcspn(word, "\n")] = '\0'; int len = strlen(word); for (int i = 0; i < len; i++) { word[i] = word[i] + 7; } printf("\n加密结果为: %s,加密密钥为: %d", word, 7); } else if (eOrD == 'd' || eOrD == 'D') { char deWord[1024] = {0}; printf("\n请输入要解密的字符串: "); fgets(deWord, sizeof(deWord), stdin); deWord[strcspn(deWord, "\n")] = '\0'; int len = strlen(deWord); for (int i = 0; i < len; i++) { deWord[i] = deWord[i] - 7; } printf("\n解密结果为: %s,解密密钥为: %d\n", deWord, 7); } else { printf("输入无效,请重试!"); } }
内容的提问来源于stack exchange,提问作者user15842907
相关产品推荐
相关产品推荐

