Thread: Vigenere - can't stop key from iterating when plaintext is non-alphabetical

  1. #1
    Registered User
    Join Date
    Aug 2019
    Posts
    2

    Vigenere - can't stop key from iterating when plaintext is non-alphabetical

    Code:
    #include <cs50.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <string.h>
    
    
    int shift(char c);
    
    
    int main(int argc, string argv[])
    {
        // Checks to make sure user enters correct number of command-line arguments
        if (argc != 2)
        {
            printf("Usage: ./vigenere keyword\n");
            return 1;
        }
        else
        {
            
            // Checks that user has only entered letters as a second command-line argument (the keyword)
            string key = argv[1];
            for (int i = 0, n = strlen(key); i < n; i++)
            {
                if (isalpha(key[i]) == 0)
                {
                    printf("Invalid keyword\n");
                    return 1;
                }
            }
            // Gets plaintext from user
            string plaintext = get_string("plaintext: ");
            printf("ciphertext: ");
            
            // Converts plain text to cipher text
            for (int l = 0, o = strlen(plaintext); l < o; l++)
            {
                int m = (l % strlen(key));
                if (islower(plaintext[l]))
                {
                    char cipheredletter = (plaintext[l] + shift(key[m]) - 97) % 26 + 97;
                    printf("%c", cipheredletter);
                }
                else if (isupper(plaintext[l]))
                {
                    char cipheredletter = (plaintext[l] + shift(key[m]) - 65) % 26 + 65; 
                    printf("%c", cipheredletter);
                }
                else
                {
                    char cipheredletter = plaintext[l];
                    printf("%c", cipheredletter);
                }
            } 
        } 
        printf("\n");
        return 0;
    }
        
    int shift(char c)
    // Converts alphabetical character to a numerical key
        
    {  
        if (islower(c))
        {
            c = c - 97;
        }
        else
        {
            c = c - 65;
        }
        return c;
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What exactly is the problem you're facing with the key for non-alphabetic characters?

    By the way, l isn't a good variable name: too easily mixed up with 1 in some fonts, and it's inconsistent with your other loop index names. Just use i like you did in your first loop, or use a more descriptive name (unneccessary in this case for a loop index). [b]o[/] is also a poorly named variable, but for the more common reason that a more descriptive variable name would be better, e.g., plaintext_len.

    You should also avoid magic numbers like 97 and 65. Either name them as constants, or in these cases you could just use 'a' and 'A'.

    I note that you aren't making good use of cipheredLetter: if you had declared the variable at the start of the inner loop then assigned to it, you could just print it once rather than in three places.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    When I asked you in your other thread to post a self-contained example, I meant something like this.
    Code:
    //!!#include <cs50.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <string.h>
    
    int shift(char c);
    
    int main()
    {
        // Examples from https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
        char key[] = "LEMON";
        char plaintext[] = "ATTACKATDAWN";
        char result[] = "LXFOPVEFRNHR";
    
        // Converts plain text to cipher text
        for (int l = 0, o = strlen(plaintext); l < o; l++)
        {
            int m = (l % strlen(key));
            if (islower(plaintext[l]))
            {
                char cipheredletter = (plaintext[l] + shift(key[m]) - 97) % 26 + 97;
                printf("%c", cipheredletter);
            }
            else if (isupper(plaintext[l]))
            {
                char cipheredletter = (plaintext[l] + shift(key[m]) - 65) % 26 + 65;
                printf("%c", cipheredletter);
            }
            else
            {
                char cipheredletter = plaintext[l];
                printf("%c", cipheredletter);
            }
        }
        printf("\n");
        return 0;
    }
    
    int shift(char c)
    // Converts alphabetical character to a numerical key
    
    {
        if (islower(c))
        {
            c = c - 97;
        }
        else
        {
            c = c - 65;
        }
        return c;
    }
    No guessing as to what to type in.
    No need for mysterious header files like cs50.h

    Now, starting from this, make an example which demonstrates the problem.

    But I kinda know already, so
    Code:
            int m = (l % strlen(key));
            if (islower(plaintext[l]))
            {
                char cipheredletter = (plaintext[l] + shift(key[m]) - 97) % 26 + 97;
                printf("%c", cipheredletter);
            }
    to
    Code:
            if (islower(plaintext[l]))
            {
                char cipheredletter = (plaintext[l] + shift(key[m]) - 97) % 26 + 97;
                printf("%c", cipheredletter);
                m = (m+1) % strlen(key);
            }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Vigenere - can't stop keyword from iterating
    By GK77 in forum C Programming
    Replies: 2
    Last Post: 09-04-2019, 08:11 AM
  2. Need help with Vigenere
    By saldar05 in forum C Programming
    Replies: 4
    Last Post: 12-24-2012, 10:21 PM
  3. Stop button doesnt stop a function (using PostMessage)
    By scwizzo in forum Windows Programming
    Replies: 7
    Last Post: 03-07-2008, 07:54 PM
  4. Processing binary or plaintext files
    By Jags in forum C Programming
    Replies: 12
    Last Post: 08-04-2006, 02:35 PM
  5. Vigenere
    By Xander in forum C++ Programming
    Replies: 1
    Last Post: 02-15-2002, 01:34 AM

Tags for this Thread