替换密码程序输出异常:含非预期字符,输入a未得预期v
替换密码加密程序异常输出问题分析
问题现象
- 执行命令
./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI并输入a时,预期输出v,但实际输出包含额外字符; - 输入文本
"Hello, Ahmed. Where are you ? Hope you are doing well."时,预期输出"Jrssb, Vjkrp. Yjrwr vwr obe ? Jbdr obe vwr pbnfg yrss.",未达成预期。
程序代码
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> int main(int argc, string argv[]) { string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; bool check_alpha = true; bool loop_check_alpha = true; //int i; //string key = argv //printf("key is %s with length %i and alphabet letters are %lu letter\n", argv[1], argc, strlen(alphabet)); if (argc < 2 || argc > 2) { printf("Usage: ./substitution key\n"); } else if (argc == 2) { for (int i = 0 ; i < strlen(argv[1]) ; i++) { if (isalpha(argv[1][i] != 0)) { check_alpha = false; } } if (strlen(argv[1]) == 26) { string message = get_string("plaintext: "); int cipher_width = 200; //get_int("put the width of your message: "); char cipher[cipher_width]; int cipher_num = 0; //printf("plaintext: %s\n", message); while (loop_check_alpha) { if (check_alpha == true) { //loop_check_alpha = false; //printf("check_alpha is %s\n", check_alpha ? "true" : "false"); for (int i = 0 ; i < strlen(alphabet) ; i++) { //printf("key letter %i is %c\n", i, argv[1][i]); //cipher_num = 0; for (int j = 0 ; j < strlen(message) ; j++) { if (message[j] == tolower(alphabet[i]) || message[j] == toupper(alphabet[i])) { if (message[j] == tolower(alphabet[i])) { cipher[j] = tolower(argv[1][i]); //if (strlen(message) < strlen(cipher)) } else if (message[j] == toupper(alphabet[i])) { cipher[j] = toupper(argv[1][i]); } //cipher_num += 1; //printf("New added letter is %c\n", argv[1][i]); } else if (isalpha(message[j]) == 0) { cipher[j] = message[j]; //printf("%c from message is printed\n", message[j]); } //printf("cipher[j] is %c, message[j] is %c, alphabet[i] is %c and argv[1][i] is %c\n", cipher[j], message[j], //alphabet[i], argv[1][i]); } } printf("message length is %lu and cipher length is %lu\n", strlen(message), strlen(cipher)); printf("ciphertext: %s\n", cipher); //if (strlen(message) == strlen(cipher)) loop_check_alpha = false; } } } } }
问题原因
- 字符数组未添加终止符:
char cipher[cipher_width];是局部未初始化数组,未手动添加字符串终止符\0。strlen(cipher)和printf("%s", cipher)会持续读取内存直到遇到\0,导致输出额外乱码。 - 密钥合法性检查逻辑错误:
if (isalpha(argv[1][i] != 0))括号位置错误,正确写法应为if (!isalpha(argv[1][i]))。原代码将argv[1][i] != 0的结果(0或1)传入isalpha,1属于可打印字符,会错误设置check_alpha = false,导致加密逻辑异常。 - 嵌套循环冗余且重复赋值:外层遍历字母表26次,每次遍历整个明文,每个明文字符被重复赋值26次,虽最后一次赋值正确,但效率极低且易引发逻辑混乱。
- 缺少密钥长度错误提示:当密钥长度不为26时,程序无任何提示直接退出,用户无法知晓失败原因。
修复后的代码
#include <cs50.h> #include <stdio.h> #include <string.h> #include <ctype.h> int main(int argc, string argv[]) { // 检查命令行参数数量 if (argc != 2) { printf("Usage: ./substitution key\n"); return 1; } string key = argv[1]; int key_len = strlen(key); // 检查密钥长度是否为26 if (key_len != 26) { printf("Key must contain 26 characters.\n"); return 1; } bool check_alpha = true; // 检查密钥是否全为字母 for (int i = 0; i < key_len; i++) { if (!isalpha(key[i])) { check_alpha = false; break; } } if (!check_alpha) { printf("Key must contain only alphabetic characters.\n"); return 1; } // 获取明文 string message = get_string("plaintext: "); int msg_len = strlen(message); // 初始化密文字符数组,预留终止符位置 char cipher[msg_len + 1]; // 加密逻辑:遍历一次明文 for (int i = 0; i < msg_len; i++) { if (islower(message[i])) { // 小写字母映射:a-z对应0-25 int idx = message[i] - 'a'; cipher[i] = tolower(key[idx]); } else if (isupper(message[i])) { // 大写字母映射:A-Z对应0-25 int idx = message[i] - 'A'; cipher[i] = toupper(key[idx]); } else { // 非字母字符直接保留 cipher[i] = message[i]; } } // 添加字符串终止符 cipher[msg_len] = '\0'; printf("ciphertext: %s\n", cipher); return 0; }
内容的提问来源于stack exchange,提问作者ahmed okka
相关产品推荐
相关产品推荐

