0

Right gentlemen. I've been really bad doing vigenere.c, doing it for 3 days in a row, I've finally made it and it passes check50 tests, but! I've 2 almost the same codes, one which should work, but it doesn't and another one which is working, with 2 more variables which we are not using in a code. What's wrong with me? This one is working

int main (int argc, string argv[])
{
    bool argvCheck;
    string vigKey = "";

    // Checking correctness of <key> and argc arguments
    do
    {
        if (argc != 2)
        {
            printf ("Something went wrong. ./vigenere <Key>\n");
            return 1;
        }
        else if(argv[1])
        {
            for(int i = 0; i < strlen(argv[1]); i++)
            {
                if(!isalpha(argv[1][i]))
                {
                    printf("Only letters should be used as a <Key>\n");
                    return 1;
                }
                else
                {
                    argvCheck = true;
                }
            }
        }
    }
    while (argvCheck == false);

    vigKey = argv[1];

    for(int i = 0; i < strlen(vigKey);i++)
    {
        vigKey[i] = tolower(argv[1][i]);
    }

    string plainText = GetString();

    for (int i = 0, ar = 0; i < strlen(plainText); i++)
    {
        if(isalpha(plainText[i]))
        {
            if (isupper(plainText[i]))
            {
                printf ("%c", ((plainText[i] - 'A') + (argv[1][ar % strlen(argv[1])] - 'a')) % 26 + 'A');
            }
            else if (islower(plainText[i]))
            {
                printf ("%c", ((plainText[i] - 'a') + (argv[1][ar % strlen(argv[1])] - 'a')) % 26 + 'a'); 
            }
            ar++;
        }
        else
            {
                printf ("%c", plainText[i]);
            }
    }
    printf ("\n");
    return 0;
}

And this one is not working

int main (int argc, string argv[])
{
    bool argvCheck;
    //string vigKey = "";

    // Checking correctness of <key> and argc arguments
    do
    {
        if (argc != 2)
        {
            printf ("Something went wrong. ./vigenere <Key>\n");
            return 1;
        }
        else if(argv[1])
        {
            for(int i = 0; i < strlen(argv[1]); i++)
            {
                if(!isalpha(argv[1][i]))
                {
                    printf("Only letters should be used as a <Key>\n");
                    return 1;
                }
                else
                {
                    argvCheck = true;
                }
            }
        }
    }
    while (argvCheck == false);

    //vigKey = argv[1];

    /*for(int i = 0; i < strlen(vigKey);i++)
    {
        vigKey[i] = tolower(argv[1][i]);
    }*/

    string plainText = GetString();

    for (int i = 0, ar = 0; i < strlen(plainText); i++)
    {
        if(isalpha(plainText[i]))
        {
            if (isupper(plainText[i]))
            {
                printf ("%c", ((plainText[i] - 'A') + (argv[1][ar % strlen(argv[1])] - 'a')) % 26 + 'A');
            }
            else if (islower(plainText[i]))
            {
                printf ("%c", ((plainText[i] - 'a') + (argv[1][ar % strlen(argv[1])] - 'a')) % 26 + 'a'); 
            }
            ar++;
        }
        else
            {
                printf ("%c", plainText[i]);
            }
    }
    printf ("\n");
    return 0;
}

As you can see there, if I get rid of vigKey, check50 says that I'm an idiot giving me these 2 errors

:( encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword
   \ expected output, but not "=aKAoh\n"
:( encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword
   \ expected output, but not "=;KA/H\n"
2

It's not so much being an idiot as it is having tunnel vision. ;-)

The problem isn't about vigKey. It's about what was done with the key string. If you look carefully at what the working code does, you'll see that the key is transformed to all lower case, so that it can be processed by subtracting 'a'. In the second version, the key isn't converted to all lower case, but it subtracts 'a' from each key letter used, even if the key letter is upper case.

You could eliminate vigKey completely and still successfully, with the following loop:

for(int i = 0, m = strlen(argv[1]); i < m; i++) 
{
    argv[1][i] = tolower(argv[1][i]);
}

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

3
  • Yes, it fixes the problem, but I still didn't get it. If I'm right, in the first code with vigKey, we're tolower(argv[1][i]) only as a reference to assign it to vigKey[i] and not changing argv[1]? Also, before posting my question here, I've tried to change printf ("%c", ((plainText[i] - 'A') + tolower (argv[1][ar % strlen(argv[1])] - 'a')) % 26 + 'A'); that bit and still unsuccessful
    – Jbwz
    Sep 30 '16 at 6:21
  • Actually, you were changing argv[1]. More specifically, you were changing the string pointed to by argv[1]. How? vigKey = argv[1]; copied the address of the string to vigKey. That means that every time the code was taking a letter from argv[1] and changing it to lower case, it was putting it right back in argv[1]. Also, you should note that a string can't be copied by simply doing a=b. You have to use a function like strcpy() or one of it's cousins. The string has to be copied from address b to address a.
    – Cliff B
    Sep 30 '16 at 6:50
  • Thank you very much! Actually just a minute ago I've finished reading chapters about pointers and pointer arrays in "C for absolute beginners" and now it's almost clear to me, especially after your explanation.
    – Jbwz
    Sep 30 '16 at 7:44

You must log in to answer this question.

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