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

bool isNumber(char number[]);

int main(int argc, string argv[])
{
    // command line argument validation
    if (argc <= 0 || argc > 2 || isNumber(argv[1]))
    {
        printf("error\n");
        return 1; //error output
    }
    else
    {
        int i;
        int j = 0;
        char ascii;
        string k = argv[1];

        //ensure if the keyword is alphabetical, if not bye bye!
        for (i = 0; i < strlen(k); i++)
        {
            if (isalpha(k[i]))
            {
                ;
            }
            else
            {
                return 1;
            }
        }


        printf("plaintext: ");
        string plaintext = get_string();

        printf("ciphertext: ");

        // iterating over the plaintext
        for (i = 0; i < strlen(plaintext); i++)
        {
            if (isalpha(plaintext[i]))
            {
                if (isupper(plaintext[i]))
                {
                    ascii = (plaintext[i] - 65) + (toupper(k[j]) - 65) % 26;
                    printf("%c", ascii + 65);
                }
                else if (islower(plaintext[i]))
                {
                    ascii = (plaintext[i] - 97) + (tolower(k[j]) - 97) % 26;
                    printf("%c", ascii + 97);
                }
                j++;
            }
            else{
                printf("%c", ' ');

                if (j >= strlen(k) - 1)
                {
                    j = 0;
                }
            }


        }
    }

    printf("\n");

    return 0;
}

bool isNumber(char number[])
{
    int i = 0;

    //checking for negative numbers
    if (number[0] == '-')
        i = 1;
    for (; number[i] != 0; i++)
    {
        //if (number[i] > '9' || number[i] < '0')
        if (!isdigit(number[i]))
            return false;
    }
    return true;
}

Please, I need help.

If I run the Walkthrough example I get a incomplete output:

$./vinegere panda plaintext: I like you ciphertext: X lvne o <- it's imcomplete

I'm reseting the j variable every time that it reaches the k(keyword) string len to start on index 0 again. The formula to swift is working but the iteration is messed up.

I need some insight, thanks.

2 Answers 2

1

The good news is that you got the concept right. J needs to be reset at a certain point. The problem with that lies here:

if (j >= strlen(k) - 1)

Why - 1???

There is an additional problem that maybe you haven't identified yet. What happens when the plaintext and the key are different cases?

And now, some notes on efficient programming. The first else statement and the associated pair of {} are unnecessary. If the first IF statement is true, the program will terminate, so an else is not needed. In fact, it opens the opportunity for error because the curly braces will embrace the entire remainder of the program needlessly.

Look at this code:

    for (i = 0; i < strlen(k); i++)
    {
        if (isalpha(k[i]))
        {
            ;
        }
        else
        {
            return 1;
        }
    }

It has a do-nothing block of code if true and an "else do-something " block. The do-nothing code is unneeded. Instead, you could do it more simply with a NOT operator, ! , like this:

    for (i = 0; i < strlen(k); i++)
    {
        if (!isalpha(k[i]))
        {
            return 1;
        }
    }

The j increment and the if statements can be simplified.

    j = (j + 1) % strlen(k);

This takes care of all of the issues.

Finally, strlen(k) is frequently used in the program. It would be more efficient to calculate it once and store the value in a variable that can be reused later. This replaces a calculation and memory read of a string array with a simple read of an int.

For you, I would say that you should always ask yourself "Is there a simpler way to do this?" With practice, these things will become second nature. ;-)

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

4
  • if (j >= strlen(k) - 1) is there to reset the j if reaches the last index of k string Commented Dec 4, 2017 at 14:49
  • I will work on the incrementation, I didn't fully understand yet Commented Dec 4, 2017 at 14:50
  • when plaintext and the key are different cases I think I solved by putting the tolower and toupper functions in each case type for plaintext Commented Dec 4, 2017 at 14:57
  • It's working! I incremented like you said. Now the check50 is showing this error message :( handles lack of argv[1] failed to execute program due to segmentation fault Commented Dec 4, 2017 at 15:50
0

When your plaintext is longer than your key, as it in this case, you need to loop around your key as with the mod operator. Essentially you want to divide the number of characters in the plaintext by the number of characters in your key to loop around the key any number of times you need.

2
  • Why would you loop around the plaintext???? You need to loop around to reuse the key while making a single pass in the plaintext.
    – Cliff B
    Commented Dec 4, 2017 at 6:25
  • sorry for the typo, #cliff is of course right, fixed reply above
    – ronga
    Commented Dec 4, 2017 at 9:05

You must log in to answer this question.

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