CS50 Problem Set 2 Substitution代码求助:check50无密文输出
CS50 Problem Set 2 Substitution作业错误排查求助
check50测试结果
- ✅ substitution.c 文件存在
- ✅ substitution.c 编译通过
- ❌ 使用密钥
ZYXWVUTSRQPONMLKJIHGFEDCBA加密"A"为"Z",预期输出"ciphertext: Z...",实际输出为空 - ❌ 使用密钥
ZYXWVUTSRQPONMLKJIHGFEDCBA加密"a"为"z",预期输出"ciphertext: z...",实际输出为空 - ❌ 使用密钥
NJQSUYBRXMOPFTHZVAWCGILKED加密"ABC"为"NJQ",预期输出"ciphertext: NJ...",实际输出为空 - ❌ 使用密钥
NJQSUYBRXMOPFTHZVAWCGILKED加密"XyZ"为"KeD",预期输出"ciphertext: Ke...",实际输出为空 - ❌ 使用密钥
YUKFRNLBAVMWZTEOGXHCIPJSQD加密"This is CS50"为"Cbah ah KH50",预期输出"ciphertext: Cb...",实际输出为空 - ❌ 使用密钥
yukfrnlbavmwzteogxhcipjsqd加密"This is CS50"为"Cbah ah KH50",预期输出"ciphertext: Cb...",实际输出为空 - ❌ 使用密钥
YUKFRNLBAVMWZteogxhcipjsqd加密"This is CS50"为"Cbah ah KH50",预期输出"ciphertext: Cb...",实际输出为空 - ❌ 使用密钥
DWUSXNPQKEGCZFJBTLYROHIAVM加密所有字母字符,预期输出"ciphertext: Rq...",实际输出为空 - ❌ 使用密钥
DWUSXNPQKEGCZFJBTLYROHIAVM不对非字母字符加密,预期输出"ciphertext: Yq...",实际输出为空 - ✅ 处理缺少密钥的情况
- ✅ 处理参数过多的情况
- ✅ 处理密钥长度无效的情况
- ✅ 处理密钥含无效字符的情况
- ✅ 处理密钥含重复字符的情况
- ✅ 处理密钥含多个重复字符的情况
我的代码
#include <cs50.h> #include <stdio.h> #include <ctype.h> #include <string.h> int main(int argc, string argv[]) { string alphabet= "abcdefghijklmnopqrstuvwxyz"; if(argc != 2) { printf("missing/more than 1 command-line argument\n"); return 1; } //check if there are 26 characters int a= strlen(argv[1]); if(a!=26) { printf("key must contain 26 characters\n"); return 1; } //Check if characters are all alphabetic for(int i=0, n=strlen(argv[1]); i<n; i++) { if(!isalpha(argv[1][i])) { printf("only alphabetic characters allowed\n"); return 1; } //check if each letter appear only once for(int j=1; j<n; j++) { if(argv[1][i]==argv[1][j]) { printf("repeated alphabets not allowed\n"); return 1; } } } //prompt user for plaintext string b= get_string("plaintext: \n"); int m=strlen(b); char ciphertxt[m+1]; //find out the alphabetical position of each character in string b (i.e character c in string b has alphabetical position of 3) for(int k=0; k<m; k++) { for(int p=0, q=strlen(alphabet); p<q; p++) { if(b[k]==alphabet[p]) { ciphertxt[k]= tolower(argv[1][p]); break; } else if(b[k]==(alphabet[p]-32)) { ciphertxt[k]= toupper(argv[1][p]); break; } else { ciphertxt[k]= b[k]; } } } ciphertxt[m]='\0'; //print ciphertext printf("ciphertext: %s\n", ciphertxt); return 0; }
错误排查与修正
核心问题1:重复字符检查逻辑错误
原代码中检查重复字符的内层循环从j=1开始,会导致自身与自身比较(比如当i=1时,j=1会触发相等判断),程序在密钥校验阶段就直接终止,根本无法进入加密步骤,所以输出为空。
修正:
- 内层循环从
j=i+1开始,避免和当前字符自身比较 - 统一转成小写后再比较,因为密钥的大小写不区分
//check if each letter appear only once for(int j = i + 1; j < n; j++) { if(tolower(argv[1][i]) == tolower(argv[1][j])) { printf("repeated alphabets not allowed\n"); return 1; } }
核心问题2:加密逻辑冗余(可选优化)
原代码用嵌套循环匹配字母位置的方式效率低且易出错,可直接通过ASCII值计算字母位置,简化逻辑:
//encrypt each character for(int k = 0; k < text_len; k++) { if(isalpha(plaintext[k])) { int pos; if(islower(plaintext[k])) { pos = plaintext[k] - 'a'; ciphertxt[k] = tolower(argv[1][pos]); } else { pos = plaintext[k] - 'A'; ciphertxt[k] = toupper(argv[1][pos]); } } else { ciphertxt[k] = plaintext[k]; } }
修正后完整代码
#include <cs50.h> #include <stdio.h> #include <ctype.h> #include <string.h> int main(int argc, string argv[]) { string alphabet = "abcdefghijklmnopqrstuvwxyz"; if(argc != 2) { printf("missing/more than 1 command-line argument\n"); return 1; } int key_len = strlen(argv[1]); if(key_len != 26) { printf("key must contain 26 characters\n"); return 1; } //Check if characters are all alphabetic and no duplicates for(int i = 0; i < key_len; i++) { if(!isalpha(argv[1][i])) { printf("only alphabetic characters allowed\n"); return 1; } for(int j = i + 1; j < key_len; j++) { if(tolower(argv[1][i]) == tolower(argv[1][j])) { printf("repeated alphabets not allowed\n"); return 1; } } } string plaintext = get_string("plaintext: "); int text_len = strlen(plaintext); char ciphertxt[text_len + 1]; for(int k = 0; k < text_len; k++) { if(isalpha(plaintext[k])) { int pos; if(islower(plaintext[k])) { pos = plaintext[k] - 'a'; ciphertxt[k] = tolower(argv[1][pos]); } else { pos = plaintext[k] - 'A'; ciphertxt[k] = toupper(argv[1][pos]); } } else { ciphertxt[k] = plaintext[k]; } } ciphertxt[text_len] = '\0'; printf("ciphertext: %s\n", ciphertxt); return 0; }
内容的提问来源于stack exchange,提问作者TSH
相关产品推荐
相关产品推荐

