CS50替换密码问题:无重复26位密钥仍被提示存在重复字符
问题修复方案
你的代码存在3个核心逻辑错误,按优先级排序如下:
- 大小写转换逻辑错误
你当前写的key[i] = islower(key[i]);中,islower()是判断类函数,返回值为布尔类型(小写字符返回非0值,非小写返回0),并非字符转换函数。你将布尔值直接赋值给key[i]后,原字符被覆盖为0或1,后续switch分支无法匹配到任何a-z字符,所有计数数组值均为0,必然触发重复字符校验错误。此处应该用tolower()函数完成大小写转换。 - switch分支缺少break语句
所有case分支执行完后没有加break,会触发switch穿透效果:只要匹配到某一个字符对应的case,后续所有case的计数器都会被+1,完全打乱字符统计结果。 - 命令行参数校验顺序错误
你先调用strlen(argv[1])再判断argv[1]是否为空,如果用户没有传入参数,argv[1]为NULL,直接调用strlen会触发段错误。需要先判断参数个数argc == 2,再处理密钥内容。
修复后完整代码
#include <stdio.h> #include <cs50.h> #include <string.h> #include <ctype.h> bool validateKey(char key[]); string substitute(char key[], string plaintext); int main(int argc, string argv[]) { // 先校验参数个数 if (argc != 2) { printf("Usage: ./substitution key\n"); return 1; } if(strlen(argv[1]) == 26) { if(validateKey(argv[1])) { string plaintext = get_string("Plaintext: "); string ciphertext = substitute(argv[1], plaintext); printf("Ciphertext: %s\n", ciphertext); } } else { printf("Key must contain 26 characters.\n"); return 1; } } bool validateKey(char key[]) { for(int i = 0; i < 26; i++) { if(!isalpha(key[i])) { printf("Key must only contain alphabetic characters.\n"); return false; } } int cntr[26] = {0}; for (int i = 0; i < 26; i++) { // 替换为tolower完成大小写转换 char lower_ch = tolower(key[i]); switch(lower_ch) { case 'a': cntr[0] += 1; break; case 'b': cntr[1] += 1; break; case 'c': cntr[2] += 1; break; case 'd': cntr[3] += 1; break; case 'e': cntr[4] += 1; break; case 'f': cntr[5] += 1; break; case 'g': cntr[6] += 1; break; case 'h': cntr[7] += 1; break; case 'i': cntr[8] += 1; break; case 'j': cntr[9] += 1; break; case 'k': cntr[10] += 1; break; case 'l': cntr[11] += 1; break; case 'm': cntr[12] += 1; break; case 'n': cntr[13] += 1; break; case 'o': cntr[14] += 1; break; case 'p': cntr[15] += 1; break; case 'q': cntr[16] += 1; break; case 'r': cntr[17] += 1; break; case 's': cntr[18] += 1; break; case 't': cntr[19] += 1; break; case 'u': cntr[20] += 1; break; case 'v': cntr[21] += 1; break; case 'w': cntr[22] += 1; break; case 'x': cntr[23] += 1; break; case 'y': cntr[24] += 1; break; case 'z': cntr[25] += 1; break; } } for(int i = 0; i < 26; i++) { if(cntr[i] != 1) { printf("Key must not contain repeated characters.\n"); return false; } } return true; } string substitute(char key[], string plaintext) { // 此处自行实现替换逻辑 return ""; }
内容的提问来源于stack exchange,提问作者user14759644
相关产品推荐
相关产品推荐

