-1

I want and searching for a function or an alternative that could replace the non-standard getch() function of C language. I want help if any any function which can replace the getch() function from the code below or an appropriate alternative.

I am doing this since my college has asked me not to use the conio.h header file in my C programs.

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

int main()
{
    int i=0, j=0, memAlloc=1;
    char *p, *q, a;
    p=(char *)calloc(1, sizeof(char));
    while(1)
    {
        a=getch();                   //getch() function 
        if(a!='\b'&&a!='\r')
        {
            p[i]=a;
            ++i;
            printf("%c", a);
            memAlloc++;
            p=realloc(p, memAlloc*sizeof(char));
        }
        if(a=='\b'&&i>=1)
        {
            printf("\b \b");
            --i;
        }
        if(a=='\r')
        {
            p[i]='\0';
            break;
        }
    }
    printf("\n");
    for (i=0; p[i]!='\0'; i++)
        printf("%c", p[i]);

    //Storing a string of only alphabets into a new dynamic array   
    q=(char *)calloc(1, sizeof(char));
    memAlloc=1;
    for (i=0; p[i]!='\0'; i++)
    {
        if (isalpha(p[I]))               //Checking for alphabet
            if(isupper(p[i]))
            {
                q[j]=p[i]+32;            //If uppercase alphabet convert it to lowercase
                memAlloc++;
                q=realloc(q, memAlloc*sizeof(char));
                j++;
            }
            else
            {
                q[j]=p[i];
                memAlloc++;
                q=realloc(q, memAlloc*sizeof(char));
                j++;    
            }           
    }
    q[j]='\0';                                         //Adding a null character to the end of the string
    free(p);
    printf("\n");
    for (i=0; q[i]!='\0'; i++)
        printf("%c", q[i]);

}

Here is the explanation of the program.

The program will take a string input from the user of unknown size and save it to the dynamic array. The user will keep on entering characters in a single line until he presses the enter key after which the whole string is saved to a dynamic array. The program then removes every character except alphabets and converting uppercase alphabets to it's lowercase and then saves the updated string to an another dynamic array.

  • you can try `getchar()` – Arpit Maiya Apr 09 '20 at 07:10
  • 4
    Yes -- with a caveat. `getch()` reads from the terminal in "raw unbuffered" mode so each keypress is taken as input without having to wait for the user to press [Enter]. The good news is all OS's/terminals provide a way to so this, the bad new is it is specific to that OS. For example Linux/gcc provides `tcsetattr` to change the input to raw-unbuffered mode (`tcgetattr` allows you to store the current settings so they can be restored when your raw input is done). The terminal mode is called non-cannonical mode for lack of better words. Many example on this site. – David C. Rankin Apr 09 '20 at 07:14
  • 1
    Does this answer: https://stackoverflow.com/questions/7469139/what-is-the-equivalent-to-getch-getche-in-linux – Support Ukraine Apr 09 '20 at 07:15
  • One important question: Is it important for you that the function does **not** wait for the press to Enter by the user - the program flow immediately continues after one character is provided - (how `getch()` does) or can you live with the waiting? That is crucial to answer your question. – RobertS supports Monica Cellio Apr 09 '20 at 07:30
  • I want the getch() way. – Debjyoti Gorai Apr 09 '20 at 07:42
  • @DebjyotiGorai At which operation system are you? Linux, Windows, Mac? – RobertS supports Monica Cellio Apr 09 '20 at 07:45
  • Windows and Linux. – Debjyoti Gorai Apr 09 '20 at 07:50
  • The only way you can do it for both Windows and Linux is to include preprocessor conditionals in your code to specifically include the windows code if compiling on windows or the unix code if compiling for Linux/Unix. You can use `#if defined (_WIN32) || defined (_WIN64)` include your windows code, `#elif __linux__` , include the Linux code, `#endif`. – David C. Rankin Apr 09 '20 at 08:34
  • Here is a Windows version: https://stackoverflow.com/a/9783195/584518 – Lundin Apr 09 '20 at 10:25

3 Answers3

0

try this scanf(" %c",&a);

also you can use getchar() but note that both of these functions(scanf and getchar()) will leave a \n in buffer and so in your next enter to loop , they will take that as input ,which means you can use two getchar() , or add a space in scanf like above.

as I see your code , you only want one character and no white-spaces which means you use scanf like above and that white space will be ignored.

hanie
  • 1,863
  • 3
  • 9
  • 19
0

If you can live with that the function will wait until it finds a newline or other whitespace character in stdin - the user needs to input more characters such as the newline made by the press to Return/ Enter - (contrary to the getch() function which does not wait for further input) you can use scanf() or getchar() (both header stdio.h) to get a single character from stdin:

a = getchar();

or

scanf("%c",&a);

Note, that in the case of getchar(), a shall be of type int instead of type char to catch the potential EOF which is returned by an error.


If you´re looking for a standard library function which does not wait for another character in stdin (unless it hasn´t encountered EOF) like getch(), the simple answer is:

There is no one. There are platform-dependent solutions only, like getch() for Windows and DOS is, but not a general standard one for all environments.

  • 1
    but scanf() will read input until it encounters an EOF, newlines or whitespace. What I really want to register every keypress as input like getch() does. – Debjyoti Gorai Apr 09 '20 at 07:45
  • @DebjyotiGorai You asked for a standard library function which does that. The simple answer is: There is no such function in the C standard library which does not wait for another character to check. – RobertS supports Monica Cellio Apr 09 '20 at 07:54
0

You can also use system command to control the terminal in linux like this:

char getch() {
        char c;

        system("stty raw -echo");
        c = getchar();
        system("stty -raw echo");

        return c;
}

This function does not require the user to press enter and takes input from the user without echoing. It requires you to add stdlib.h library to your code

Note: This function is only applicable to UNIX-based OS

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • 1
    Why use shell instead of `tcgetattr` and `tcsetattr`, considering `stty` is mostly a shell front-end for those? – moshbear Apr 30 '21 at 04:28