0

Good day everyone. I am trying to do a Vigenere cipher code in C and I have done something that is wrong and I can't fix it. I have documented my code as best as I can to make you know my intentions

    #include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
    if (argc == 2)
    {
     string keyword = argv[1];//step 1: Get keyword from commandline argument

       for (int i = 0, n = strlen(keyword); i < n; ++i )//step 2:  Keyword must be alphabetic    
    {
        if (!isalpha(keyword[i]))
        {
            printf("second argument should be a string of alphabets \n");
            return 1;
        }
    }       

    printf("plaintext: ");  //step 3: Prompt for plaintext
    string p = get_string();
    printf("ciphertext: ");


    if( p != NULL) 
    {
       for (int i = 0, n = strlen(p); i < n; ++i)  // Go through every character in the plaintext
            {
                int indexOfKeyword = keyword[i % strlen(keyword)];   
                if (isalpha(p[i]))  //if a character in the plaintext is an alphabet 
                {

                    if (isupper(p[i]))   //if character in the plaintext is a capital letter
                    {  
                keyword[indexOfKeyword] = keyword[indexOfKeyword] - 'A';
               p[i]  = p[i] - 'A'; // preserve the plaintext's case by converting to its alphabet position using this formula

                //use the alphabet position in the formula to get the new alphabet position and convert back to ascii
              printf("%c",( (p[i] + keyword[indexOfKeyword + 1 % strlen(keyword)]) % 26 ) + 'A');
                    }

             if (islower(p[i]))
                   {
                keyword[indexOfKeyword] = keyword[indexOfKeyword] - 'a';
               p[i]  = p[i] - 'a'; // preserve the plaintext's case by converting to its alphabet position using this formula
               //c[i] = ((p[i] + keyword[i]) % 26) + 'a';      //use the alphabet position in the formula to get the new alphabet position and convert back to ascii
              printf("%c",( (p[i] + keyword[indexOfKeyword + 1 % strlen(keyword)]) % 26 ) + 'a');
                   }

          }

        else
        {
            //c[i] = p[i];//don't shift plaintext character if it is a symbol just put it in c
            printf("%c",p[i]);
        }
    }
    }                               


    printf("\n");
    return 0;

}

else
{
    printf("Program should have 2 arguments!\n");
    return 1;
}

    return 0;

}

1 Answer 1

1

After edit:

Giving keyword it's own subscript k is a step in the right direction. However, it is still tied to p in this loop for (int i = 0, k=0, n = strlen(p); i < n; ++i,++k). If k is being incremented at the same rate as i, well, still the same problem. And the modulus (keyword[k%n]) cannot be tied to the length of p. In this example it will go way out of bounds.

The combination of this char c[strlen(p)]; and this n = strlen(c) is going to give you trouble. When you use a string function (in this case strlen(c)), the computer expects the argument c to be a real, valid, string. The thing that makes a string a string is the terminating null byte. Here it has been declared a char array, and it has no terminating null byte (nor space for one!). If it is too daunting to make c a realio-trulio string, consider saving the length of p in a variable after p is created, and using that for the output iteration.


From the spec (emphasis added):

Your program must only apply Vigenère’s cipher to a character in p if that character is a letter. All other characters (numbers, symbols, spaces, punctuation marks, etc.) must be outputted unchanged. Moreover, if your code is about to apply the jth character of k to the ith character of p, but the latter proves to be a non-alphabetical character, you must wait to apply that jth character of k to the next alphabetical character in p; you must not yet advance to the next character in k.

The "secret" message here: the plaintext and the key do not "run at the same rate". p[i] will not necessarily be encrypted by k[i]!

3
  • I appreciate your response...but I still don't get it Commented May 7, 2017 at 17:04
  • @DinoCodeSaurus... I edited the code to the best of my knowledge Commented May 7, 2017 at 17:14
  • Perhaps this short from last year's material will clarify. i is incremented for each iteration. You are still missing "you must wait" and "you must not yet advance" Commented May 9, 2017 at 10:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .