Abhishek kumar Abhishek kumar - 4 months ago 29
C Question

Vigenere Cipher

i am facing the problem while running the below code designed for vigenere cipher.even after going thoroughly i am not able to debug the problem. it is showing the error:killed by server.please help.

/**
*
* vigenere.c
*
* Abhishek kumar
* encrypts entered string using vigenere cipher
* */
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>

int main(int argc, string argv[] )
{
if (argc != 2)
{
printf("Usage: /home/cs50/pset2/vigenere <keyword>");
return 1;
}

if (argc == 2)
{ string key = argv[1];
for(int k = 0,l = strlen(key);k < l; k++)
{
if(!isalpha(key[k]))
{
printf("Keyword must only contain letters A-Z and a-z");
exit(1);
}

}


string txt = GetString();
int i = 0,j = 0,c = 0;
int n = strlen(txt);
int m = strlen(key);
while(i < n)
{
if (isupper(txt[i]))
{
if(isupper(key[j]))
{
c = ((((int) txt[i] - 65 + (int) key[j] -65)%26) + 65);
printf("%c", (char) c);
i++;
j++;
}
if(islower(key[j]))
{
c = ((((int) txt[i] - 65 + (int) key[j] -97)%26) + 65);
printf("%c", (char) c);
i++;
j++;
}

}
else if (islower(txt[i]))
{
if(isupper(key[j]))
{
c = ((((int) txt[i] - 97 + (int) key[j] -65)%26) + 97);
printf("%c", (char) c);
i++;
}
if(islower(key[j]))
{
c = ((((int) txt[i] - 97 + (int) key[j] -97)%26) + 97);
printf("%c", (char) c);
j++;
}


}
else
{
printf("%c",txt[i]);
i++;

}
if (j == m-1)
{
j = 0;
}
}




}
}


below are some of the test cases in which it is failing.

:) vigenere.c exists
:) vigenere.c compiles
:( encrypts "a" as "a" using "a" as keyword
\ killed by server
:( encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword
\ killed by server
:( encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword
\ expected output, but not "CGSFpp"
:( encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword
\ expected output, but not "CASFPO"
:) handles lack of argv[1]
:) handles argc > 2
:) rejects "Hax0r2" as keyword

Answer

In the islower(txt[i]) section, you fail to increment i and j in all cases. In the place where you don't increment i, i.e. where the first character of the key and the text are both lower case, you end up with an infinite loop.

In the isupper(txt[i]) section, you increment i and j in the isupper(key[j]) part, then you enter the islower(key[j]) part because you use if instead of else if.

For both of the above, change if(islower(key[j])) to else if(islower(key[j])), and move j++ and the printf after each inner if block. As for i, change while to a for and increment i as part of that.

When checking to see if you should reset j, you're off by 1. m-1 is a valid index for key so you don't want to reset yet. Do it when j == m.

Also, replace the ASCII codes with the actual characters they represent so it's more clear what you're doing. The casts aren't needed either.

    for (i=0; i < n; i++)
    {
        if (isupper(txt[i]))
        {
            if(isupper(key[j]))
            {
                c = (((txt[i] - 'A' + key[j] -'A')%26) + 'A');
            } 
            else if(islower(key[j]))
            {
                c = (((txt[i] - 'A' + key[j] -'a')%26) + 'A');
            }
            printf("%c", c);
            j++;
        }
        else if (islower(txt[i]))
        {
            if(isupper(key[j]))
            {
                c = (((txt[i] - 'a' + key[j] -'A')%26) + 'a');
            } 
            else if(islower(key[j]))
            {
                c = (((txt[i] - 'a' + key[j] -'a')%26) + 'a');
            }
            printf("%c", c);
            j++;
        }
        else
        {
            printf("%c",txt[i]);
        }
        if (j == m)
        {
            j = 0;
        }
    }
Comments