Search code examples
ccaesar-cipher

Not accepting other option entered by user


I have to do the caesar cipher in C. Encryption and decrytion depending on the key and password (4 characters maximun) plus shifting direction, all three are given by the user. In my code it only takes left, and when I enter right it re-asks for the direction again. I don't know what's wrong.

Here's my code:

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

char pass[4];
char shiftdirection[6];
char left[6] = "left";
char right[6] = "right";
char ch;
int i, key;

void readline (){ //cette fonction prend de l'utilisateur le password et la clé
    do{
    printf("Please enter the pass, max 4 characters: \n");
    gets(pass);
    }while((strlen(pass)>4) || (strlen(pass)<4)); //get the password from th
    printf("Please enter the key: \n");
    scanf("%d",&key);
}

//cette fonction utilisée pour chiffrer
void encrypt(){
    printf("Enter the direction: \n");
    scanf("%s", &shiftdirection);
    while ((strcmp(shiftdirection,left)==1) || (strcmp(shiftdirection,right)==1)) { // demander de l'utilisateur la direction de décalage

        printf("Enter the direction: \n");
        scanf("%s", &shiftdirection);
    }
    if(strcmp(shiftdirection,left)==0){ // si l'utilisateur a écrit left, le programme commence le chiffrage avec un décalage à gauche
    for( i = 0; pass[i] != '\0'; i++){
        ch = pass[i];
        if(ch >= 'a' && ch <= 'z'){
            ch = (char) (ch + key);
            if(ch > 'z'){
                ch = (char) (ch - 'z' + 'a' - 1);
            }
            pass[i] = ch;
        }
        else if(ch >= 'A' && ch <= 'Z'){
            ch = (char) (ch + key);
            if(ch > 'Z'){
                ch = (char) (ch - 'Z' + 'A' - 1);
                }
            pass[i] = ch;
            }
        }
    }
   else if(strcmp(shiftdirection,right)==0){ // si l'utilisateur a écrit left, le programme commence le chiffrage avec un décalage à gauche
        for( i = strlen(pass) - 1; i >= 0; --i){
            ch = pass[i];
            if(ch >= 'a' && ch <= 'z'){
                ch = (char) (ch + key);
                if(ch > 'z'){
                    ch = (char) (ch - 'z' + 'a' - 1);
                }
                pass[i] = ch;
            }
            else if(ch >= 'A' && ch <= 'Z'){
                ch = (char) (ch + key);
                if(ch > 'Z'){
                    ch = (char) (ch - 'Z' + 'A' - 1);
                }
                pass[i] = ch;
            }
        }
    }
    printf("Encrypted Password is %s", pass); // le password chiffré
}

//cette fonction utilisée pour déchiffrer
void decrypt(){
    for(i = 0 ; pass[i] != '\0' ; ++i){
        ch = pass[i];
        if(ch >= 'a' && ch <= 'z'){
            ch = (char) (ch - key);
            if(ch < 'a') {
                ch = (char) (ch + 'z' - 'a' + 1);
            }
            pass[i] = ch;
        } else if (ch >= 'A' && ch <= 'Z'){
            ch = (char) (ch - key);
            if(ch < 'A'){
                ch = (char) (ch + 'Z' - 'A' + 1);
            }
            pass[i] = ch;
        }
    }
    printf("\nDecrypted Password is %s", pass); //le password déchiffré
}
//main
int main() {
    readline();
    encrypt();
    decrypt();
    return 0;
}

INPUT AND OUTPUT


Solution

    1. As people in the comments mentioned you have to change the char pass[4] -> char pass[5] to consider the \0 or \n from pressing return.
    2. Do not use gets. Use fgets instead cause gets is unsafe and not part of C anymore
    3. Use getchar() to capture leftover \0 by the press of return
    4. change scanf to scanf_s for more secure
    5. Your while ((strcmp(shiftdirection,left)==1) || (strcmp(shiftdirection,right)==1)) checks if one of the conditions isn't true then enters. You need to check if both conditions are not true so you need && instead of ||

    I have played with your code a little bit and came up with the following.

    Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char pass[5];
    char shiftdirection[6];
    char left[6] = "left";
    char right[6] = "right";
    char ch;
    int i, key;
    
    void readline (){ //cette fonction prend de l'utilisateur le password et la clé
        do{
        printf("Please enter the pass, max 4 characters: \n");
        fgets(pass, sizeof pass, stdin);
        }while((strlen(pass)>4) || (strlen(pass)<4)); //get the password from th
        printf("Please enter the key: \n");
        scanf_s("%d",&key);
        getchar();
    }
    
    //cette fonction utilisée pour chiffrer
    void encrypt(){
        printf("Enter the direction: \n");
        fgets(shiftdirection, sizeof shiftdirection, stdin);
        shiftdirection[strcspn(shiftdirection, "\n\r")] = 0;
        while ((strcmp(shiftdirection,left)==1) && (strcmp(shiftdirection,right)==1)) { // demander de l'utilisateur la direction de décalage
    
            printf("Enter the direction: \n");
            fgets(shiftdirection, sizeof shiftdirection, stdin);
            shiftdirection[strcspn(shiftdirection, "\n\r")] = 0;
        }
        if(strcmp(shiftdirection,left)==0){ // si l'utilisateur a écrit left, le programme commence le chiffrage avec un décalage à gauche
        for( i = 0; pass[i] != '\0'; i++){
            ch = pass[i];
            if(ch >= 'a' && ch <= 'z'){
                ch = (char) (ch + key);
                if(ch > 'z'){
                    ch = (char) (ch - 'z' + 'a' - 1);
                }
                pass[i] = ch;
            }
            else if(ch >= 'A' && ch <= 'Z'){
                ch = (char) (ch + key);
                if(ch > 'Z'){
                    ch = (char) (ch - 'Z' + 'A' - 1);
                    }
                pass[i] = ch;
                }
            }
        }
       else if(strcmp(shiftdirection,right)==0){ // si l'utilisateur a écrit left, le programme commence le chiffrage avec un décalage à gauche
            for( i = strlen(pass) - 1; i >= 0; --i){
                ch =pass[i];
                if(ch >= 'a' && ch <= 'z'){
                    ch = (char) (ch + key);
                    if(ch > 'z'){
                        ch = (char) (ch - 'z' + 'a' - 1);
                    }
                    pass[i] = ch;
                }
                else if(ch >= 'A' && ch <= 'Z'){
                    ch = (char) (ch + key);
                    if(ch > 'Z'){
                        ch = (char) (ch - 'Z' + 'A' - 1);
                    }
                    pass[i] = ch;
                }
            }
        }
        printf("Encrypted Password is %s", pass); // le password chiffré
    }
    
    //cette fonction utilisée pour déchiffrer
    void decrypt(){
        for(i = 0 ; pass[i] != '\0' ; ++i){
            ch = pass[i];
            if(ch >= 'a' && ch <= 'z'){
                ch = (char) (ch - key);
                if(ch < 'a') {
                    ch = (char) (ch + 'z' - 'a' + 1);
                }
                pass[i] = ch;
            } else if (ch >= 'A' && ch <= 'Z'){
                ch = (char) (ch - key);
                if(ch < 'A'){
                    ch = (char) (ch + 'Z' - 'A' + 1);
                }
                pass[i] = ch;
            }
        }
        printf("\nDecrypted Password is %s", pass); //le password déchiffré
    }
    //main
    int main() {
        readline();
        encrypt();
        decrypt();
        system("pause");
        return 0;
    }
    

    Note that shiftdirection[strcspn(shiftdirection, "\n\r")] = 0; checks the string for leftover \n so getchar() might be subtituted.

    I hope this is what you are looking for

    Edit: Your while((strlen(pass)>4) || (strlen(pass)<4)); is basically while(strlen(pass)!=4); which means that pass should always be 4 characters long. Is that the case? or the user can also enter less than 4?

    Update:

    Checked the

    while ((strcmp(shiftdirection,left)==1) && strcmp(shiftdirection,right)==1)) condition again, cause it was wrong.

    Change it to while ((strcmp(shiftdirection,left)!=0) && (strcmp(shiftdirection,right)!=0)).

    When strcmp(shiftdirection,left) or strcmp(shiftdirection,right) are not left or right accordingly, the value is -1 not 1.