Search code examples
ccs50vigenere

Vigenere failed test :( encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword


Can someone help me with my code to solve this error above?I have searched for answers but they are bit different from my code.

  • vigenere.c compiles.
  • encrypts "a" as "a" using "a" as keyword
  • encrypts "barfoo" as "caqgon" using "baz" as keyword
  • encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword
    failed expected "ciphertext: CaQ...", not "ciphertext: CaQ..."
  • encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword
  • encrypts "world!$?" as "xoqmd!$?" using "baz" as keyword
  • encrypts "hello, world!" as "iekmo, vprke!" using "baz" as keyword
  • handles lack of argv[1]
    failed failed to execute program due to segmentation fault
  • handles argc > 2
  • rejects "Hax0r2" as keyword

#include<stdio.h>
#include<cs50.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>


int main(int argc,string argv[])
{
    for (int k = 0;k<strlen(argv[1]);k++)
    {
        if (isalpha(argv[1][k]))
        {}
        else
        {
            return EXIT_FAILURE;
        }
    }
    if (argc == 2)
    {
        int alpha,cipher,key,j=0,len=strlen(argv[1]);
        char a;
        string plaintext = get_string("Text: ");
        printf("ciphertext: ");
        for (int i = 0; i<strlen(plaintext) ; i++)
        {
            if (isalpha(plaintext[i]))
            {
                if (isupper(plaintext[i]))
                {
                    alpha = plaintext[i]-65;
                    key = argv[1][j]-65;
                    cipher = (key+alpha)%26;
                    a = (char) cipher+65;
                    printf("%c",a);
                    j=(j+1)%len;

                }
                else if (islower(plaintext[i]))
                {
                    alpha = plaintext[i]-97;
                    key = argv[1][j]-97;
                    cipher = (key+alpha)%26;
                    a = (char) cipher+97;
                    printf("%c",a);
                    j=(j+1)%len;
                }

            }
            else
            {
                printf("%c",plaintext[i]);
            }
        }
        printf("\n");
    }
    else
    {
        printf("error\n");
        return EXIT_FAILURE;
    }
}

Solution

  • Your code handles upper and lowercase letters in the plaintext correctly, but it doesn't handle different case letters in the keyword properly. When you're processing an uppercase plaintext letter, you subtract 65 from the keyword letter, even though it might not be uppercase.

    You should simply convert all keyword letters to a common case, and subtract the corresponding first letter from that to get the amount to increase by.

    There's also no need to check islower() -- if it's not uppercase, it must be lowercase. So just use else.

                if (isupper(plaintext[i]))
                {
                    alpha = plaintext[i]-'A';
                    key = toupper(argv[1][j])-'A';
                    cipher = (key+alpha)%26;
                    a = (char) cipher+'A';
                    printf("%c",a);
                    j=(j+1)%len;
    
                }
                else
                {
                    alpha = plaintext[i]-'a';
                    key = toupper(argv[1][j])-'A';
                    cipher = (key+alpha)%26;
                    a = (char) cipher+'a';
                    printf("%c",a);
                    j=(j+1)%len;
                }
    

    To fix the segmentation fault due to lack of argv[1], move the loop that checks that the keyword is all alphabetic inside the if (argc == 2) block. You can also then use the len variable instead of repeating strlen(argv[1]) in the loop.