0

I'm making a multi-feature command-line application where users have features like encrypt-decrypt a string, check string palindrome and reverse a string, and I started to write my whole code with the encrypt-decrypt feature, but apparently it is not working as expected, sometimes it encrypts/decrypts the string, the same code when executed again exits itself without taking the string input! I have even inserted the fflush(stdin), but no luck!

#include <stdio.h>

void encryptDecrypt();
// void checkPalindrome();
// void reverseWord();

void main()
{
    int choice;
    printf("\nWelcome to Jeel's multi-feature C App\n\n");
    printf("1. Encrypt-Decrypt a word\t2. Check Palindrome\t3. Reverse a word\n\n");
    printf("Enter a feature: ");
    scanf("%d", &choice);
    switch (choice)
    {
    case 1:
        fflush(stdin);
        encryptDecrypt();
        break;

    case 2:
        // checkPalindrome();
        break;

    case 3:
        // reverseWord();
        break;

    default:
        break;
    }
}

void encryptDecrypt()
{
    fflush(stdin);
    char eOrD;
    printf("\nWelcome to the World of Encryption & Decryption! We're so glad that you're here!\n\n");
    printf("Enter 'e' if you want to encrypt a word or 'd' if you want to decrypt a word (e/d): ");
    scanf("%c", &eOrD);
    if (eOrD == 'e' || eOrD == 'E')
    {
        fflush(stdin);
        char *word;
        printf("\nGreat! Now enter a word to encrypt it: ");
        fflush(stdin);
        gets(word);

        char *ptr = word;
        for (int i = 0; i < sizeof(ptr); i++)
        {
            if (*ptr != '\0')
            {
                *ptr = *ptr + 7;
                ptr++;
            }
        }
        printf("\nEncrypted string is: %s, which is encrypted with the key: %d", word, 7);
    }
    else if (eOrD == 'd' || eOrD == 'D')
    {
        fflush(stdin);
        char *deWord;
        printf("\nGreat! Now enter a word to decrypt it: ");
        gets(deWord);
        char *dePtr = deWord;
        for (int i = 0; i < sizeof(dePtr); i++)
        {
            if (*dePtr != '\0')
            {
                *dePtr = *dePtr - 7;
                dePtr++;
            }
        }
        printf("\nDecrypted string is: %s, which is decrypted with the key: %d\n", deWord, 7);
    }
    else
    {
        printf("Invalid input! Please try again!");
    }
}
Botje
  • 26,269
  • 3
  • 31
  • 41
  • 2
    Please don't spam language tags. You don't use a single C++ feature. – Botje Nov 22 '21 at 09:59
  • 3
    Undefined behaviour here: `char *word; gets(word);` The `word` pointer is uninitialised, therefore indeterminate, so sometimes it appears to "work", by bad luck. It must have memory allocated to it, either by being an array, or a dynamic allocation. – Weather Vane Nov 22 '21 at 10:00
  • 3
    [fflush(stdin) considered harmful](https://stackoverflow.com/questions/2979209/using-fflushstdin) –  Nov 22 '21 at 10:01
  • 1
    Passing an input-only stream (like `stdin`) to the `fflush` function is officially *undefined behavior*. – Some programmer dude Nov 22 '21 at 10:01
  • 3
    Also function `gets()` is obsolete and is no longer part of the standard C library. Please read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – Weather Vane Nov 22 '21 at 10:02
  • @Someprogrammerdude You mean, that the fflush(stdin) no longer should be used? Can you share the alternative methods for it? –  Nov 22 '21 at 10:49
  • @WeatherVane Noted! and it worked, thanks! –  Nov 22 '21 at 10:51
  • @dratenik I'll now be careful with that! Thanks for sharing! –  Nov 22 '21 at 10:52
  • @Botje Okay! Sorry! –  Nov 22 '21 at 10:52
  • 1
    It's explicitly mentioned in the C specification, and have *never* been valid. One big compiler unfortunately have added it as a non-standard and non-portable extension. The way around it is to create a new function which reads input character by character (discarding all of them) until a newline or `EOF`. (And remember that all character-reading functions returns an **`int`**, to be able to properly handle `EOF`) – Some programmer dude Nov 22 '21 at 10:52
  • @Someprogrammerdude Ohh, I see! –  Nov 22 '21 at 10:54

1 Answers1

1

The best and most portable way to clear the stdin is using this:

void clearStream()
{
    int c;
    while ((c = getchar()) != '\n' && c != EOF) { }
}

Also the following is incorrect, create an array instead of the pointer:

char *word;
gets(word); //word is a pointer, gets will not create a block of memory for it
aliberro
  • 530
  • 2
  • 9