Search code examples
cencryption

Encrypting/Decrypting (Reading a string and changing the string with certain characters)


I've been learning C and i decided to start a project, Encrypt and Decrypt in ROT13 since i just tought it was the easiest to start with.

I cant seem to figure a way to read the string and change the characters acording to ROT13, i was thinking about a dictionary but i also cant seem to figure that out and use it

I tried LUT but couldnt manage to make it work because everything i found was way too hard for me to understand. I was expecting to just replace every letter with the correspondign one with a lot of Switch or If's but i just know that its not something good to do. I also cant seem to insert the string with fgets, for some reason it just prints ���x�_�����0�x�_

#include <stdio.h>

// https://rot13.com/

void Encrypt()
{
    char text[50];
    printf("Insert the desired text (Maximum of 50 characters): \n");
    fgets(text, sizeof(text), stdin);
    for (int i = 0; i < sizeof(text); i++)
    {
        printf("%c", text[i]);
    }
}

int main()
{
    int menu;
    while (menu == 0)
    {
        printf("Choose one of the following options: \n");
        printf("[1] Encrypt\n");
        printf("[2] Decrypt\n");

        scanf("%i", &menu);

        if (menu == 1)
        {
            Encrypt();
        }
        if (menu == 2)
        {
            // Decrypt();
        }
    }
}

Solution

  • When you use scanf to get the menu choice from the user, the newline character is left in the buffer. When you then use fgets to read in a line, it sees the newline, and so reads just that one character. The rest of your text array is left uninitialized, and so when you print it you get that newline character followed by gibberish.

    You can see how this works by entering, at the menu prompt:

    1 aaaaaaaaaaaaaaaaaa
    

    You'll now see the aaaaaaaaaaaaaaaaaa followed by a newline and then gibberish.

    You can use fgets and sscanf to handle the menu choice. Barring a very long line of input, this will read an entire line, leaving nothing in the buffer for the next scanf or fgets call to read. If you are concerned with very long lines, memory is typically cheap. Use a larger buffer size, like 1024.

    You'll also want to check that sscanf succeeded and handle the error if it didn't.

    int main() {
        while (1) {
            printf("Choose one of the following options: \n");
            printf("[1] Encrypt\n");
            printf("[2] Decrypt\n");
    
            char input[50];
            int menu;
    
            fgets(input, sizeof(input), stdin);
    
            if (sscanf(input, "%i", &menu) != 1) {
                fprintf(stderr, "Invalid input\n");
                continue;
            }
    
            switch (menu) {
            case 1:
                Encrypt();
                break;
            
            case 2:
                // Decrypt();
                break;
    
            default:
                fprintf(stderr, "Invalid menu choice.\n");
            }
        }
    }