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

int main(int argc, string argv[])
{
    // checks if there is a k
    if (argv[1] != NULL)
    {
        // puts the key in 'k'
        string k = argv[1];
        // gets all k capitalized
        for (int l = 0; l < strlen(k); l++)
        {
            k[l] = toupper(k[l]);
        }
        // checks if k is letters
        if (argc == 2)
        {
            // asks the user for a string 'p'
            printf("plaintext: ");
            string p = get_string();
            // looping through 'p'
            printf("ciphertext: ");
            for (int j = 0; j < strlen(p); j++)
            {
                // cyphers capitalized letters
                if (isupper(p[j]))
                {
                    int c = ((int) p[j]-65 + (int) k[j%strlen(k)]-65) % 26;
                    printf("%c", (char)c+65);
                }
                // cyphers non-capitalized letters
                else if (islower(p[j]))
                {
                    int c = ((int) p[j]-97  + (int) k[j%strlen(k)]-65) % 26;
                    printf("%c", (char)c + 97);
                }
                // prints what's not a letter
                else
                {
                    printf("%c", p[j]);
                }
            }
        }
        else
        {
            printf("error\n");
            return 1;
        }
        printf("\n");
        return 0;
    }
    else
    {
        printf("error\n");
        return 1;
    }
}

That's my code. When I run it with:

./vigenere ABC plaintext: HELLO

it gives: ciphertext: URYYB

Can someone help me understand why and where I'm wrong?

Thank you

PS: I'm 75% sure the problem is in the if's of the actual ciphers

edit1: I've fixed most issues but my key doesn't wrap around well when plaintext has non letter characters. I've updated the code to the newest one

1

I see most of the most common issues. Let's look at the conversion:

int c = ((int)p[j] - 65 + (int)k[i]) % 26;

This code is adding the ASCII value of the key to the converted value of the plaintext letter. It should be adding the converted value of the key letter.

Next, I don't see any code to handle the cases where the plaintext and the key are not the same case.

Tip: if isupper() or islower() return true on a given value, that value is also automatically isalpha() by definitiion. Testing for isalpha is redundant.

There may be other issues but this will get you going again.

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

4
  • I really appreciate your comment. So I've fixed most issues now. The only problem I have is when a word has numbers or other non-letter characters my key doesn't wrap around well. int c = ((int) p[j]-65 + (int) k[j%strlen(k)]-65) % 26; printf("%c", (char)c+65); So using a key ABC in a word like HE11O the last O doesn't get ciphered by a C, but gets ciphered by a B. Any idea on how to improve my code? I'm getting 80% score now because it checks all the words except the ones with non-letters characters.
    – Pexan
    Aug 24 '17 at 12:20
  • I've updated OP with the newest code
    – Pexan
    Aug 24 '17 at 12:27
  • @P.Coelho You need to keep a seperate counter for the key. Right now you're telling it to use k[j%strlen(k)] which means the position depends on j. But j increments with every character in the plaintext, and you want the index for k to increment only every time you need to use it.
    – robert_x44
    Aug 24 '17 at 19:54
  • thank you robert_x44. I've figured the problem
    – Pexan
    Aug 25 '17 at 20:16

You must log in to answer this question.

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