【发布时间】:2023-09-28 17:21:01
【问题描述】:
我遇到了 CS50 的替换密码问题。我被困在如何验证密钥上。每当我将 26 个字符的键作为命令行参数传递时,即使该键没有任何字符,程序也会输出“您不得重复任何字符”。我的程序正确地检查了密钥的长度和命令行参数的存在。它只是不承认有效的非重复密钥。
#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(strlen(argv[1]) == 26) { //key typed after prgm name will be used to encrypt data
if(validateKey(argv[1])) {
string plaintext = get_string("Plaintext: ");
string ciphertext = substitute(argv[1], plaintext);
printf("Ciphertext: %s", ciphertext);
}
}
else if(argv[1] == NULL) {
printf("Usage: ./substitution key\n");
}
else {
printf("Key must contain 26 characters.\n");
}
}
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;
}
}
/*
an array of counters to keep track of how many times a letter occurs in the cipher
each counter should be set to 1 if key doesn't have repeating letters
*/
int cntr[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 26; i++) {
key[i] = islower(key[i]); //make all the letters in the key lowercase to make it easier to work with
switch(key[i]) {
case 'a':
cntr[0] += 1;
case 'b':
cntr[1] += 1;
case 'c':
cntr[2] += 1;
case 'd':
cntr[3] += 1;
case 'e':
cntr[4] += 1;
case 'f':
cntr[5] += 1;
case 'g':
cntr[6] += 1;
case 'h':
cntr[7] += 1;
case 'i':
cntr[8] += 1;
case 'j':
cntr[9] += 1;
case 'k':
cntr[10] += 1;
case 'l':
cntr[11] += 1;
case 'm':
cntr[12] += 1;
case 'n':
cntr[13] += 1;
case 'o':
cntr[14] += 1;
case 'p':
cntr[15] += 1;
case 'q':
cntr[16] += 1;
case 'r':
cntr[17] += 1;
case 's':
cntr[18] += 1;
case 't':
cntr[19] += 1;
case 'u':
cntr[20] += 1;
case 'v':
cntr[21] += 1;
case 'w':
cntr[22] += 1;
case 'x':
cntr[23] += 1;
case 'y':
cntr[24] += 1;
case 'z':
cntr[25] += 1;
}
}
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[]) {
return "";
}
【问题讨论】:
-
将
break添加到每个case。 -
一种更紧凑的方法是将整个
switch块替换为一行:cntr[key[i] - 'a'] += 1;。 -
整个
switch语句可以只替换为cntr[key[i] - 'a'] += 1。 -
key[i] = islower(key[i]);->key[i] = tolower(key[i]);。您可能想要执行char k = tolower(key[i]);和switch(k)之类的操作,以避免修改原始密钥。 -
@kaylum:上次我检查过,您必须在 C 的初始化程序中提供至少一个值(C++ 允许您省略它)。 MSVC 不需要 IIRC(它允许在 C 中使用很多 C++ 主义),但它是非标准的。至少根据cppreference's page on C array initialization,它至少需要一个表达式,所以我认为我没记错规则。