-1

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;
                }
            }
        }
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Have you tried running your code line-by-line in a debugger while monitoring the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Sep 12 '22 at 23:07
  • Note that CS50 has its own debugger, which is called [debug50](https://video.cs50.io/v_luodP_mfE?screen=J0ND72qsI9U&start=1688&end=2012). – Andreas Wenzel Sep 12 '22 at 23:07
  • yes, I did so and found that when it checks the if statements inside second for loop with J incremental factor and the 2 ifs come to false result it add the non ascii letters to cipher value but there is nothing inside the code do so. so why ? – ahmed okka Sep 12 '22 at 23:10
  • Side note: You can change `if (argc < 2 || argc > 2)` to `if ( argc != 2 )` and you can change the line `else if (argc == 2)` to `else`. This does not change the behavior of the program, but is simpler and easier to read. – Andreas Wenzel Sep 12 '22 at 23:21
  • you can consider this as command ./substitution VCHPRZGJNTLSKFBDQWAXEUYMOI and a as input which suppose to output v but it doesn't output v only – ahmed okka Sep 12 '22 at 23:41
  • 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. – ahmed okka Sep 12 '22 at 23:54

1 Answers1

3

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++)
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39