Search code examples
ccs50vigenere

My "Vigenere CS 50" project doesn't work well


I'm currently working on Vigenere CS 50 Problem. The code seems working pretty well, but sometimes the output is being confused by further symbols just being added at the end of the output string. For instance when I'm encrypting "a" with a key of "a" the output will be sometimes just ok as "a" and sometimes can look like "a<" or "aR" or "a{7"...

At the same time, the code works ok with much longer keys and more complex plain text, so I'm really confused now and do not really know what to start with.

Could you please have a look of the code?

Thanks in advance, Vladimir

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

int main(int argc, string argv[])
{
    if (argc != 2)
    {
    printf("Usage: ./vigenere k\n");
    return 1;
    } 

    string k = (argv[1]);

    int key[strlen(k)];

    int n = strlen(k);

    for (int i = 0; i < n; i++)
    {
        if (isalpha(k[i]))
        {
            if (isupper(k[i]))
            {
                key[i] = (int)k[i] - 65;
            }
            else
            {
                key[i] = (int)k[i] - 97;
            }
        }
        else 
        {
            printf("Key must be alphabetical\n");
            return 1;
        }
    }

    string p;

    do 
    {
        printf("plaintext: ");
        p = get_string();
    } while (p == NULL); 

    char c[strlen(p)];

    int cn = 0;

    for (int j = 0, m = strlen(p); j < m; j++)
    {
        if (isalpha(p[j]))
        {
            if (isupper(p[j])) 
            {
                c[j] = (((int)p[j] + key[cn] - 65) % 26 + 65);
            }
            else
            {
                c[j] = (((int)p[j] + key[cn] - 97) % 26 + 97);
            }

            cn++;
            cn = cn % n;
        }
        else 
        {
            c[j] = p[j];
        }
    }

    printf("ciphertext: %s", c);
    printf("\n");

    return 0;

}

Solution

  • It's a good old fashioned "not null terminated" string. C style strings (which is what you've created with char c[strlen(p)];) have no length associated with them. To calculate their length, the standard library assumes they'll be terminated with \0 (a null byte). You're not doing this, so when you printf, it carries on printing until it finds one.

    You need to:

    1. Allocate enough space for the null byte: char c[strlen(p) + 1];
    2. Put it on the end: c[strlen(p)] = 0;