code from this blog

int kbhit()
{
    struct timeval tv;
    fd_set fds;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
    return FD_ISSET(STDIN_FILENO, &fds);
}
void nonblock(int state)
{
    struct termios ttystate;

    //get the terminal state
    tcgetattr(STDIN_FILENO, &ttystate);

    if (state==NB_ENABLE)
    {
        //turn off canonical mode
        ttystate.c_lflag &= ~ICANON;
        //minimum of number input read.
        ttystate.c_cc[VMIN] = 1;
    }
    else if (state==NB_DISABLE)
    {
        //turn on canonical mode
        ttystate.c_lflag |= ICANON;
    }
    //set the terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);

}
int main()
{
    char c;
    int i=0;

    nonblock(NB_ENABLE);
    while(!i)
    {
        usleep(1);
        i=kbhit();
        if (i!=0)
        {
            c=fgetc(stdin);
            if (c=='q')
                i=1;
            else
                i=0;
        }

        fprintf(stderr,"%d ",i);
    }
    printf("\n you hit %c. \n",c);
    nonblock(NB_DISABLE);

    return 0;
}

This is the only example of "non-enter" input I've been able to find. Is this code portable between operating systems and compilers? Any reason why it wouldn't be a good idea to use?

Recommended Answers

All 4 Replies

>>s this code portable between operating systems

No. Works only on MS-Windows because it appears to be using win32 api functions. There is no portable way to do what you want using any standard C or C++ functions. There are non-standard functions, such as ncurses which I know has been ported between MS-Windows and *nix. Functions in conio.h may also do it, but that is not only os dependent but also compiler dependent.

>>Any reason why it wouldn't be a good idea to use?
Depends on the compiler you are using. Since you brought up portability then you probably don't want to use that.

No it's not portable at all. That's why it's not recommended.

C/C++ does not have a standard way to accept input without a Return.

The code is not portable. It is very linux-specific. It uses termios, and it assumes that stdin is selectable.
Another problem is that it doesn't test the select error code. When select returns -1, the fds is undefined, and kbhit would return garbage.
Otherwise, it is a fairly standard way to achieve the goal, although I prefer a portable setvbuf(stdin, 0, _IONBF, 0) .

setvbuf does not produce the same result. It doesn't remove the need hit enter/return. Suppose I'll deal with ncurses.

commented: you are right about setvbuf. +27
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.