Search code examples
cvigenerecs50

What's wrong with my CS50 Vigenere code?


I've been going round in circles with this now for a few hours. It manages the first word of the recommended test (Meet me at the park at eleven am) gets over the first spaces, gives a correct letter for m then prints several spaces before ending. Many thanks in advance.

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

int allstralpha();

int main(int argc, string argv[])
{
    string keyw = argv[1];
    if(argc == 2 && allstralpha(keyw))
    {
        string plaint = GetString();
        int c = 0;
        int kl = strlen(keyw);
        int k = 0;
        int p = 0;
        int j = 0;
        for(int i = 0, n = strlen(plaint); i < n; i++)
        {      
            if(isalpha(plaint[i]))
            {        
                if(isupper(keyw[j]))
                {
                    k = keyw[(j % kl)] - 65;
                    if(isupper(plaint[i]))
                    {
                        p = plaint[i] -65;
                        c = ((k + p) % 26) + 65;
                        printf("%c", (char) c);                     
                    }   
                    else if(islower(plaint[i]))
                    {
                        p = plaint[i] -97;
                        c = ((k + p) % 26) + 97;
                        printf("%c", (char) c);
                    }
                }
                else if(islower(keyw[j]))
                {   
                    k = keyw[(j % kl)] - 97;
                    if(isupper(plaint[i]))
                    {  
                        p = plaint[i] - 65;                                  
                        c = ((k + p) % 26) + 65;             
                        printf("%c", (char) c);

                    }
                    else if(islower(plaint[i]))
                    {
                        p = plaint[i] - 97; 
                        c = ((k + p) % 26) + 97;
                        printf("%c", (char) c);
                    }   
                }
                j++;    
            }
            else
            {
                printf("%c", (char) plaint[i]);
            }
        }       
    }
    else
    {
        printf("Sorry that is not a vaild parameter\n");
        return 1;
    }  
}
int allstralpha(string s)
{   
    for(int i = 0, n = strlen(s); i < n; i++)
    {
        if(!isalpha(s[i]))
        {
        return 0;
        }
    }
    return 1; 
}

Solution

  • int allstralpha();
    int allstralpha(string s)
    {   
    ...
    }
    

    Your function definition and declaration don't match. You should declare int allstralpha(string s);

    In first line of main:

    int main(int argc, string argv[])
    {
        string keyw = argv[1];
        ...
    }
    

    First you should check if (argc > 1) before accessing argv[1]

    For the actual code itself, you provide the plain text, but I can't see the keyword.

    I use these values from wikipedia, vigenère cipher for testing:

    Plaintext:  ATTACKATDAWN
    Key:        LEMONLEMONLE
    Ciphertext: LXFOPVEFRNHR
    

    Minimum code to finish this:

    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    int main(int argc, const char* argv[])
    {
        const char *str = "Meet me at the park at eleven am";
        const char *key = "bacon";
    
        int keylen = strlen(key);
        int len = strlen(str);
        for (int i = 0, j = 0; i < len; i++)
        {
            int c = str[i];
            if (isalnum(c))
            {
                //int k = function of key and `j`...
                //offset k...
                if (islower(c))
                {
                    c = (c - 'a' + k) % 26 + 'a';
                }
                else
                {
                    c = (c - 'A' + k) % 26 + 'A';
                }
                j++;
            }
            putchar(c);
        }
        putchar('\n');
        return 0;
    }