why the cipher message contain letters which isn't belong to ASCII code

Viewed 55

I am actually trying to make a code that encrypt messages so that I can input any text message as input in cmd and got the encryption for the alphabetical letters and leave other letters as they are but while I am trying to do so I got unexpected output message with extra letters can anybody explain to me what is going on ?

When I run the program with the command ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI and a as input, it is supposed to output v but it doesn't output v only.

or "Hello, Ahmed. Where are you ? Hope you are doing well." as input with "Jrssb, Vjkrp. Yjrwr vwr obe ? Jbdr obe vwr pbnfg yrss." as output.

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

int main(int argc, string argv[])
{
    string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    bool check_alpha = true;
    bool loop_check_alpha = true;
    //int i;
    //string key = argv
    //printf("key is %s with length %i and alphabet letters are %lu letter\n", argv[1], argc, strlen(alphabet));
    if (argc < 2 || argc > 2)
    {
        printf("Usage: ./substitution key\n");
    }
    else if (argc == 2)
    {
        for (int i = 0 ; i < strlen(argv[1]) ; i++)
        {
            if (isalpha(argv[1][i] != 0))
            {
                check_alpha = false;
            }
        }
        if (strlen(argv[1]) == 26)
        {
            string message = get_string("plaintext:  ");
            int cipher_width = 200;
            //get_int("put the width of your message: ");
            char cipher[cipher_width];
            int cipher_num = 0;
            //printf("plaintext:  %s\n", message);
            while (loop_check_alpha)
            {
                if (check_alpha == true)
                {
                    //loop_check_alpha = false;
                    //printf("check_alpha is %s\n", check_alpha ? "true" : "false");
                    for (int i = 0 ; i < strlen(alphabet) ; i++)
                    {
                        //printf("key letter %i is %c\n", i, argv[1][i]);
                        //cipher_num = 0;
                        for (int j = 0 ; j < strlen(message) ; j++)
                        {
                            if (message[j] == tolower(alphabet[i]) || message[j] == toupper(alphabet[i]))
                            {
                                if (message[j] == tolower(alphabet[i]))
                                {
                                    cipher[j] = tolower(argv[1][i]);
                                    //if (strlen(message) < strlen(cipher))
                                }
                                else if (message[j] == toupper(alphabet[i]))
                                {
                                    cipher[j] = toupper(argv[1][i]);
                                }
                                //cipher_num += 1;
                                //printf("New added letter is %c\n", argv[1][i]);
                            }
                            else if (isalpha(message[j]) == 0)
                            {
                                cipher[j] = message[j];
                                //printf("%c from message is printed\n", message[j]);
                            }
                            //printf("cipher[j] is %c, message[j] is %c, alphabet[i] is %c and argv[1][i] is %c\n", cipher[j], message[j],
                            //alphabet[i], argv[1][i]);
                        }
                    }
                    printf("message length is %lu and cipher length is %lu\n", strlen(message), strlen(cipher));
                    printf("ciphertext: %s\n", cipher);
                    //if (strlen(message) == strlen(cipher))
                    loop_check_alpha = false;
                }
            }
        }
    }
}
1 Answers

When using printf with the %s conversion format specifier, you are required to pass a null-terminated string as an argument to the function.

However, in the line

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

cipher is not necessarily terminated by a null terminating character, because you never set any character to this value.

This explains why your program is printing "garbage" characters after the intended characters. The function printf is probably printing everything it finds in memory as a character, until it happens to find a null character.

Therefore, to fix the problem, you can either add a terminating null character to cipher, or you can limit the number of characters printed by printf, for example like this:

printf( "ciphertext: %.*s\n", (int)strlen(message), cipher );

If you want to solve the problem by adding a terminating null character, I recommend that you write cipher[j] = '\0'; immediately after the inner loop. However, since j goes out of scope as soon as the loop ends, you will have to move the declaration of j outside the inner loop, by adding int j; outside the loop and changing the line

for (int j = 0 ; j < strlen(message) ; j++)

to:

for (j = 0 ; j < strlen(message) ; j++)
Related