1

I am a beginner programmer taking a free class and I am having a lot of trouble with a simple Meyer's encryption scheme for security based encryption and decryption. I cannot work on the decryption because I cant even get the encryption to work. We are required to add necessary prompts etc to make sure the correct things are entered by the user. Here is my code:

int main (void)
{

const int N = 10;
char message [N];
char processed[N];
char selection;

void encrypt_msg(char msg[],char encrypted[]);

printf("Please enter a message: ");
fgets (message, N, stdin);
printf("%s\n",message);
printf("Would you like to encrypt <E>, or decrypt <D> this message?");
scanf(" %c\n",&selection);
if (selection == 'E')
{
    encrypt_msg(message,processed);
    printf("%s\n",processed);
    return 0;
}
if (selection != 'E')
{
    printf("Invalid selection, please enter <E> or <D> ");
}

}
void encrypt_msg(char msg[],char encrypted[])
{
    int i;
    int NL;
    for (i=0;msg[i]!='\0';i++)
    {
    while (msg[i]<'z'&&msg[i]>'A')
    {
        NL=msg[i]+i+1;
        while (NL<'z')
        {
            NL=NL;
        }
        while(NL>'z')
        {
            NL=NL-26;
        }
        encrypted[i]=msg[i]+1;
     }

    }

}

The problem is that when the user inputs "E", the program will immediately go to the "invalid input" if statement and bypass the actual encryption function. It may be doing something entirely different but I don't know because I am horrible. 'NL' is for the new letter that is to replace the old letter based on the M.E.S.S key.

Anne
  • 11
  • 2
  • 1
    `NL = NL;`? Why? – Fred Larson Jan 31 '20 at 18:59
  • i guess to specify that if the letter was not going to shift out of range that the new shifted letter wouldnt change.. – Anne Jan 31 '20 at 19:03
  • 2
    I strongly advice against `scanf()` for reading input like this, perhaps even more so for a single character. Read another full line with `fgets()`, then inspect that. It's much more robust. Failing that, *at least* add error-detection code to the `scanf()` call; it has a return value you know. I/O can and will fail. – unwind Jan 31 '20 at 19:11
  • I'm getting different behavior than you're describing. For me, it goes into `encrypt_msg()` and then gets in an infinite loop. The outer `while` loop will never terminate (`msg[i]` is not changed in the loop), and neither will the `while (NL < 'z')` loop (`NL` is not changed in the loop). – Fred Larson Jan 31 '20 at 19:13
  • The posted code does not compile! amongst other things, it is missing the needed `#include` statements for the needed header files – user3629249 Feb 01 '20 at 15:01
  • regarding: `while (msg[i]<'z'&&msg[i]>'A')` What are you trying to check with this statement? perhaps you are thinking of `isprint()` from the header file: `ctype.h`. And why exclude 'z' and 'A'? – user3629249 Feb 01 '20 at 15:09
  • OT: for ease of readability and understanding: 1) please consistently indent the code. Indent after EVERY opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks: `for` `if` `else` `while` `do...while` `switch` `case` `default` via a single blank line. 3) separate functions by 2or 3 blank lines (be consistent). 4) insert a 'reasonable' space inside parens, inside braces, inside brackets, after semicolons, after commas, around C operators – user3629249 Feb 01 '20 at 15:16
  • regarding: `while (NL<'z') { NL=NL; } while(NL>'z') { NL=NL-26; }` What about when `NL` == `z`? – user3629249 Feb 01 '20 at 15:20
  • regarding this kind of statement: `if (selection == 'E')` Much better to check for either upper or lower case. I.E. `if ((toupper(selection) == 'E')` Where `toupper()` is from the header file: `ctype.h` – user3629249 Feb 01 '20 at 15:24
  • the encryption stops if a space, digit, comma, etc is encountered in the 'msg[]` Probably not a good idea – user3629249 Feb 01 '20 at 15:35
  • there are several characters between the end of the upper case characters and the beginning of the lower case characters (in ASCII format) I would expect the posted code would not really want to process them. – user3629249 Feb 01 '20 at 15:38
  • regarding: `scanf(" %c\n",&selection);` That trailing '\n' in the format string results in ALL trailing white space being consumed. AND results in the the function not exiting until a non-white space is encountered. However, that is very unlikely to happen, so the function does not return – user3629249 Feb 01 '20 at 15:46

2 Answers2

1

have you tried scanf("%c",&selection); without '\n' ?

  • that ends up passing over the ability for the user to enter their selection and just ends the program :( – Anne Jan 31 '20 at 19:08
  • The leading space in before the `%c` is important; the absence of the `\n` after `%c` is crucial. See [What is the effect of trailing white space in a `scanf()` format string?](https://stackoverflow.com/q/19499060/15168) and [`scanf()` leaves the newline in the input buffer](https://stackoverflow.com/q/19499060/15168). – Jonathan Leffler Jan 31 '20 at 19:15
  • I ran your program with that modification and the program enters to first condition, but the implementation of encrypt_msg maybe is not ok. I would recommend that you'll try your function 'encrypt_msg' with a given string and if you see it works fine, try with the user input. – Axel Cervantes Jan 31 '20 at 19:22
1

First of all a great idea would be indenting, helps a lot especially in lengthy projects/scripts.

Moreover try simplifying you if statements for the sake of your own debug. Now comes the fun part, after rewriting the critical section of your code to meet my "habits" seems like fully working!

What I added/removed was:

  • if - else statement instead of the old one;
  • fflush(stdin) since seemed to lag on my machine;
  • removed that peculiar "\n" from the scanf() section.
int main()
{

    int N = 10;
    char message [N];
    char processed[N];
    char selection;



    printf("Please enter a message: ");
    fgets (message, N, stdin);


    printf("%s\n",message);

    fflush(stdin);
    printf("Would you like to encrypt <E>, or decrypt <D> this message?");

    scanf("%c",&selection);



    if (selection == 'E' || selection == 'e')
    {

        printf("Im into it\n");
        //Do the actual function calls below 


    }
    else if(selection == 'D' || selection == 'd')
    {
        // Do what you would do to decrypt the msg

    }
    else
    {
        printf("Invalid selection, please enter <E,e> or <D,d> ");
    }

    return 0;

}
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
apfel
  • 31
  • 3
  • per the C standard, `fflush(stdin)` is undefined behavior. Suggest: `int ch; while( ( ch = getchar() ) != '\n' && ch != EOF )` Note: `fflush()` is only for output streams – user3629249 Feb 01 '20 at 15:04
  • Could work on input as well, at least based on my understanding and you're right concerning the "undefined behavior" part. Yet is a bad habit of mine to use the fflush() – apfel Feb 03 '20 at 04:46