0

Folks, I have been dealing with vigenere problem for a while, however one issue that keeps occurring impedes my progress. The thing is that each time key wraps around itself, first value it returns is 0, so basically I get key[j] = 0, which in turn outputs nothing, followed by letter that should not be there. For example, here is an output that demonstrates this pictorially. *note: key is baz

key[j] is:a text[i]: w key[i]:b
key[j] is:z text[i]: o key[i]:a
key[j] is:  text[i]: r key[i]:z

count:1
key[j] is:a text[i]: l key[i]:
key[j] is:z text[i]: d key[i]:X

So I wonder why this value is getting lost every time? Seems like "b" is being overwritten by blank space.

Here goes the code:

note:key wrapper is at the bottom

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

//change converting mechanism!
int main(int argc, char* argv[])
{
    //checking if user have provided key. If not, inform user and exit
    if (argc != 2)
    {
        printf("Usage: ./vigenere <key>\n");
        return 1;
    }

    char* key = argv[1];
    int keylen = strlen(argv[1]);
    int j = 0;
    int count = 0;

    if (!isalpha(key[0]))
    {
        printf("Please provide a string\n");
        return 1;
    }

    char* text = GetString();
    //int textlen = strlen(text);

    for(int i = 0, n = strlen(text); i < n; i++)
    {
        if(!isalpha(text[i]))
        {
            int cipher = text[i];
            printf("%c",(char) cipher);
        }

        if(isupper(text[i]))
        {
            if(text[i] + key[j] >= 156)
            {
                int cipher = (text[i] + key[j] - 'A') % 26 + 'A';
                printf("%c", (char) cipher);
            }
            else
            {
                int cipher = (text[i] + key[j] - 'A');
                printf("%c", (char) cipher);
            }
        }

        if(islower(text[i]))
        {
            if(text[i] + key[j] >= 220)
            {
                int cipher = (text[i] + key[j] - 'a') % 26 + 'a';
                printf("%c", (char) cipher);
            }
            else
            {
                int cipher = (text[i] + key[j] - 'a');
                printf("%c", (char) cipher);
            }

            printf("key[j]_1: %i\n", key[j]);
        }

        //printf("oldj:%i\n", j);

        if(j >= keylen)
        {
            j++;
            j = j % keylen;
            count++;
            printf("count:%i\n", count);
        }
        else
        {
            j++;
        }
        printf("key[j]_2: %i\n", key[j]);
        //printf("key[j] is:%c text[i]: %c key[i]:%c\n", (char) key[j],(char) text[i], (char)key[i]);
        //if
    }
    printf("\n");
}
0

I don't understand exactly what 156 and 220 you have hardcoded are. If the text[i] is uppercase you should subtract 'A' while when it's lowcase you should subtract 'a'.

Then you should do the same for your key[j]. And only then if their sum is out of bounds, meaning after 25 (since we are from [0 - 25]) only then you should wrap to the beginning of the alphabet and add back the 'A' or 'a' you subtracted from text[i].

And to answer your question about the last missing letter of key, say key is "baz", so keylen is 3. You have:

if(j >= keylen)
{
    j++;
    j = j % keylen;
    count++;
    printf("count:%i\n", count);
}
else
{
    j++;
}
  • At first j == 0 and you cypher with key[0], then it goes to the else block and j becomes 1.
  • Then j == 1 and you cypher with key[1], then it goes to the else block and j becomes 2.
  • Then j == 2 and you cypher with key[2], then it goes to the else block and j becomes 3.
  • Then j == 3 and you cypher with key[3], but there is no key[3] only 0, 1 and 2. That's where the empty space character comes from.

There are also more problems with your code, like that you don't check if the whole key is alphabetical, you check only for the first letter. Start by correcting your cyphering and you will solve those later. You are quite close to the solution, just your cyphering is a little wrong. Don't overcomplicate things in your mind. Subtract simple letters from both key and text, add them together, and then check if a wrapping around is needed.


If this answers your question please accept it by clicking the gray check-mark to the left, so that it becomes green. You can also vote it up by pressing the up arrow above the check-mark. And don't forget to keep coding!

You must log in to answer this question.