Click here to Skip to main content
15,892,674 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello!!
I'm using C language and I want to use an input ,without waiting for user input or pushing enter.(in python I can do this)-I guess here too.
For example,I want to print "hello\n" in console inside a while-loop and when user gives an input I want to print the given input ,without stop printing message "hello".

What I have tried:

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

int main(void)
{
initscr();
noecho();
cbreak(); // don't interrupt for user input
timeout(500); // wait 500ms for key press
char c;
int a = 1;
while(a == 1)
{
  c = getch();
  printf("hello\n");
  printf("%c key pressed...\n",c);
}
  endwin();
  nocbreak();
}



but I got this error:

/tmp/ccNmVWH7.o: In function `main':
input_no_wait.c:(.text+0x9): undefined reference to `initscr'
input_no_wait.c:(.text+0xe): undefined reference to `noecho'
input_no_wait.c:(.text+0x13): undefined reference to `cbreak'
input_no_wait.c:(.text+0x1a): undefined reference to `stdscr'
input_no_wait.c:(.text+0x27): undefined reference to `wtimeout'
input_no_wait.c:(.text+0x2e): undefined reference to `stdscr'
input_no_wait.c:(.text+0x36): undefined reference to `wgetch'
input_no_wait.c:(.text+0x54): undefined reference to `endwin'
input_no_wait.c:(.text+0x59): undefined reference to `nocbreak'
collect2: error: ld returned 1 exit status


--------------------------------------------------------------
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0



I want your help.

Thanks in advance!!!
Posted
Updated 12-Apr-22 10:26am
v3

I would have the main process working on one thread and the "waiting for user input" on another. Have a look at Using Worker Threads[^] for more info (sorry it uses C++ but look for the principles)
Another - this one in C# but the principles remain the same A Concise Overview of Threads[^]
An external (to Codeproject) article on Threading in C is this one from Cornell University[^]
 
Share this answer
 
Comments
Nick_is_asking 5-Aug-20 6:46am    
Is there anything else,because I don't understand??
CHill60 5-Aug-20 7:56am    
Well you could look at the curses (programming library) - Wikipedia[^]
At some stage I advise you to get your head around threading though
Nick_is_asking 5-Aug-20 8:18am    
I tried this one code:

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

int main(void)
{
initscr();
noecho();
cbreak(); // don't interrupt for user input
timeout(500); // wait 500ms for key press

int c = getch();
printf("%c\n",c);
endwin();
nocbreak();
return 0;
}


but I got this error:

/tmp/ccNmVWH7.o: In function `main':
input_no_wait.c:(.text+0x9): undefined reference to `initscr'
input_no_wait.c:(.text+0xe): undefined reference to `noecho'
input_no_wait.c:(.text+0x13): undefined reference to `cbreak'
input_no_wait.c:(.text+0x1a): undefined reference to `stdscr'
input_no_wait.c:(.text+0x27): undefined reference to `wtimeout'
input_no_wait.c:(.text+0x2e): undefined reference to `stdscr'
input_no_wait.c:(.text+0x36): undefined reference to `wgetch'
input_no_wait.c:(.text+0x54): undefined reference to `endwin'
input_no_wait.c:(.text+0x59): undefined reference to `nocbreak'
collect2: error: ld returned 1 exit status
CHill60 5-Aug-20 12:22pm    
Looks like the flags you have set on your Link options are incorrect. You'd have to share details of how you are compiling/linking. Might be best to put that in a separate question as it's not really related to your original question here. Make sure you include details of the IDE or Linker you are using as well as the options that you are using
Nick_is_asking 5-Aug-20 12:52pm    
I compile like this: gcc name.c name and run like this ./name
I just want to get an input without waiting for user input and without pushing [ENTER] button.
Check this:

C++
/**
 Linux (POSIX) implementation of _kbhit().
 Morgan McGuire, morgan@cs.brown.edu
 how to get a character from stdin without waiting for user to put it in C? */
#include <stdio.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>


int kbhit() {
    static const int STDIN = 0;
    static int initialized = 0;

    if (! initialized) {
        // Use termios to turn off line buffering
        struct termios term;
        tcgetattr(STDIN, &term);
        term.c_lflag &= ~ICANON;
        tcsetattr(STDIN, TCSANOW, &term);
        setbuf(stdin, NULL);
        initialized = 1;
    }

    int bytesWaiting;
    ioctl(STDIN, FIONREAD, &bytesWaiting);
    return bytesWaiting;
}

//////////////////////////////////////////////
//    Simple demo of _kbhit()

#include <unistd.h>

int  getch(void) {
    struct termios oldattr, newattr;
    int ch;
    tcgetattr( STDIN_FILENO, &oldattr );
    newattr = oldattr;
    newattr.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
    return ch;
}

int main(int argc, char** argv) {
    printf("Press any key");
    while (! kbhit()) {
        printf(".");
        fflush(stdout);
        usleep(1000);
    }
    printf("\nDone. Las chars %d\n", getch());

    return 0;
}
 
Share this answer
 
I found a solution ,but I have to push a key I want twice instead of once.
Here is the code and I think the problem is to getch().
Can you help me to fix this problem(I want to push a button once and not twice).
Code:
C++
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/select.h>


int kbhit(void);
int getch(void);

int kbhit(void)
{
  struct timeval tv;
  fd_set read_fd;

  /* Do not wait at all, not even a microsecond */
  tv.tv_sec=0;
  tv.tv_usec=0;

  /* Must be done first to initialize read_fd */
  FD_ZERO(&read_fd);

  /* Makes select() ask if input is ready:
   * 0 is the file descriptor for stdin    */
  FD_SET(0,&read_fd);

  /* The first parameter is the number of the
   * largest file descriptor to check + 1. */
  if(select(1, &read_fd,NULL, /*No writes*/NULL, /*No exceptions*/&tv) == -1)
    return 0;  /* An error occured */

  /*  read_fd now holds a bit map of files that are
   * readable. We test the entry for the standard
   * input (file 0). */
  
if(FD_ISSET(0,&read_fd))
    /* Character pending on stdin */
    return 1;

  /* no characters were pending */
  return 0;
}




int  getch(void) {
    struct termios oldattr, newattr;
    int ch;
    tcgetattr( STDIN_FILENO, &oldattr );
    newattr = oldattr;
    newattr.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
    return ch;
}



int main(){
        int a = 1;
   while(a == 1){
      if(kbhit() == 0){
         getch();
                 printf("%c is pressed\n",getch());
         
      }  
   }
  return 0;
}



For example, if I press 'a' and then again 'a' ,then I recieve -> a is pressed.
But I want to press 'a' only once to recieve -> a is pressed.
I need your help.

Thanks in advance...
 
Share this answer
 
Comments
Richard MacCutchan 7-Aug-20 12:01pm    
Exactly what problem are you trying to solve? Using a console app in this way is very old fashioned.
Nick_is_asking 12-Aug-20 16:28pm    
I want to build snake game in terminal with C and I don't know what input to use to move snake.So simple.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900