0

Below is my code to solve the substitution problem in pset 2:

#include <math.h>
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <stdbool.h>


int main(int argc, string argv[])
{
    // setting up key requirments
    // check if E key and length
    if (argc != 2 || strlen(argv[1]) != 26)
    {
        printf("Usage ./substitution key\n");
        return 1;
    }
    else
    {
        for (int i = 0 ; i < strlen(argv[1]) ; i++)
        {
            for (int j = 0; j < strlen(argv[1]); j++)
            {
                // check if key is unique
                if (isalpha(argv[1][i]) == false || (tolower(argv[1][i]) == tolower(argv[1][j]) && i != j ) )
                {
                    printf("Usage ./substitution key\n");
                    return 1;
                }
            }
        }
    }
    
    // prompt user for plain text input
    string plain = get_string("plaintext: ");
    string alpha = "abcdefghijklmnopqrstuvwzyz";
    string key = argv[1];
    int n = strlen(plain);
    string ciph = plain;  
    
    for (int i = 0; i < n; i++) //going through the plain text index's 
    {
        if (isupper(plain[i]) != 0)
        {
            for (int j = 0; j < strlen(alpha); j++) // going through the alpha index's
            {
                if (tolower(plain[i]) == alpha[j])
                {
                    ciph[i] = toupper(key[j]); 
                }
            }
        }
        else if (isupper(plain[i]) == 0)
        {
            for (int j = 0; j < strlen(alpha); j++) // going through the alpha index's
                {
                    if (tolower(plain[i]) == alpha[j])
                    {
                        ciph[i] = tolower(key[j]); 
                    }
                }
        }
    }
    
    printf("%i\n", n);
    printf("%i\n", (int) strlen(ciph));
    printf("ciphertext: %s\n", ciph);
    return 0;
}

I understand the key validation part of the question and I thought I did the substitution part correctly, however when I try to convert "Hello, world" using the key provided on the course website (JTREKYAVOGDXPSNCUIZLFBMWHQ) I get "Bdxxn, mnixd" which I know is wrong bc the first letter should be "V" instead of "B". The thing is when I switch line 39 to char ciph[n] I get an output of "Vkxxn" for "Hello, world". So the first world is correct but it doesn't translate past that. Does anyone know why this is happening? Any help would be really appreciated!

0

The problem here arises from a nuance of memory management:

string ciph = plain;

When you declare this variable, you are not creating a copy of plain; rather, you create a second pointer pointing to the same location in memory (you've inadvertently stumbled upon a problem that will make a lot more sense to you in future weeks of the course).

When you change ciph[i] in your loop, you are changing the memory it points to, and therefore the result of plain[i] changes as well. So your loop correctly assigns the letter V for the first substitution, but then it keeps running, and finds a match for V (which is B) and substitutes again.

The simplest solution is to add a break statement in each loop directly after you assign ciph[i].

1
  • Additionally, you could do away with the intermediary alpha key and the associated search loops entirely if you approach the ASCII value of each character mathematically.
    – Sentox
    Nov 16 '20 at 22:42

You must log in to answer this question.

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