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);

Другие вопросы по тегам