Vigenere шифр трудности
Это шифр Vigenere для CS50. Это мой первый код, и я обхожу это вокруг уже неделю, и мне кажется, что я не могу напечатать первое письмо после того, как цикл завершится в первый раз.
Например:
jharvard @ appliance (~ / Dropbox):./viginere abcde Твой ключ abcde Введите текст: ааааа аааааа ааааааа аааааааа abcde bcde bcdebc debcde
Первый a
печатается, но затем начинается b
и в конце концов, он не печатает каждую букву. Ключ выбирается пользователем.
Понятия не имею, что я делаю не так.
for (int i = 0, j = strlen(plain_text), l = 0; i < j; i++)
{
int rotation_1 = (tolower(plain_text[i]) + (key[l] - 97)) % 122;
int rotation_2 = (plain_text[i] + (key[l] - 97)) % 122;
//if it is a letter
if (isalpha(plain_text[i]))
{
l = l % strlen(key);
//if the it is uppercase
if (isupper(plain_text[i]))
{
printf("%c", toupper(rotation_1));
}
//else if it is lowercase
else
{
printf("%c", rotation_2);
}
l++;
}
// if it is not a letter we print it as it is
else
{
printf("%c", plain_text[i]);
}
}
1 ответ
Вот более простая версия с исправленной логикой:
for (int i = 0, n = strlen(plain_text), k = 0, klen = strlen(key); i < n; i++) {
int c = (unsigned char)plain_text[i];
//if it is a letter
if (isalpha(c)) {
if (isupper(c)) {
c = 'A' + (c - 'A' + key[k] - 'a') % 26;
} else {
c = 'a' + (c - 'a' + key[k] - 'a') % 26;
}
k = (k + 1) % klen;
}
putchar(c);
}
Важно разыграть plain_text[i]
как (unsigned char)
так как isalpha
а также isupper
определены только для всех значений unsigned char
а также EOF
, char
может быть подписан по умолчанию вашей платформы.
Также обратите внимание, что putchar(c)
гораздо эффективнее, чем printf("%c", c);