tags:

views:

755

answers:

5

Hi,

I am trying to do a C++ program where when user enter any character from keyboard it should move to next line of code.

Here is my code:

char c;

cin>>c;

cout<<"Something"<<endl;

but this is not working because it only move to next line when i input some character and then press ENTER.

OR

If i use this

cin.get() or cin.get(c)

it move to next line of instruction when i press Enter.

But i wanted it to move to next line on any key pressed on the keyboard, how this can be done?

+2  A: 

To achieve this functionality you could use ncurses library which was implemented both on Windows and Linux (and MacOS as far as I know).

Kirill V. Lyadvinsky
Well this is kind of an assignment in which i cannot use any external libraries etc, so just have to stay in "chapter context" lox.
itsaboutcode
Then the only option is to implement needed functionality for each OS you are planning to support.
Kirill V. Lyadvinsky
ncurses is more or less a VT200 client. A bit overkill for simply reading from the TTY.
greyfade
+3  A: 

If you're on Windows, you can use kbhit() which is part of the Microsoft run-time library. If you're on Linux, you can implement kbhit thus (source):

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

I'm not sure if this'll work on OS X, but it's worth a try.

Vinay Sajip
It's a shame that there is not standard way to handle the console, you always have to use some OS magick
Vargas
True. Consoles have been de-emphasised since the advent of GUIs.
Vinay Sajip
+2  A: 

You can use the getchar routine.

From the above link:

/* getchar example : typewriter */
#include <stdio.h>

int main ()
{
  char c;
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");
  do {
    c=getchar();
    putchar (c);
  } while (c != '.');
  return 0;
}
Nick D
I don't think this is what the OP was asking for, if I understand him correctly. You still have to press ENTER to fill the buffer before getchar() can read from it.
Lucas
A: 

I looked into what you are trying to achieve, because I remember I wanted to do the same thing. Inspired by Vinay I wrote something that works for me and I sort of understand. But I am not an expert, so please be careful.

I don't know how Vinay knows you are using Mac OS X. But it should work kind of like this with most unix-like OS. Really helpful as resource is opengroup.org

Make sure to flush the buffer before using the function.

#include <stdio.h>
#include <termios.h>     //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>  //STDIN_FILENO


void pressKey()
{
    //the struct termios stores all kinds of flags which can manipulate the I/O Interface
    //I have an old one to save the old settings and a new 
    static struct termios oldt, newt;
    printf("Press key to continue....\n");

    //tcgetattr gets the parameters of the current terminal
    //STDIN_FILENO will tell tcgetattr that it should write the settings
    // of stdin to oldt
    tcgetattr( STDIN_FILENO, &oldt);
    //now the settings will be copied 
    newt = oldt;

    //two of the c_lflag will be turned off
    //ECHO which is responsible for displaying the input of the user in the terminal
    //ICANON is the essential one! Normally this takes care that one line at a time will be processed
    //that means it will return if it sees a "\n" or an EOF or an EOL
    newt.c_lflag &= ~(ICANON | ECHO );   

    //Those new settings will be set to STDIN
    //TCSANOW tells tcsetattr to change attributes immediately. 
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    //now the char wil be requested
    getchar();

    //the old settings will be written back to STDIN
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

}


int main(void)
{
  pressKey();
  printf("END\n");
  return 0;
}

O_NONBLOCK seems also to be an important flag, but it didn't change anything for me.

I appreciate if people with some deeper knowledge would comment on this and give some advice.

Lucas
O_NONBLOCK should be set because without it, getchar() (which calls read()) will block waiting for input. The kbhit() solution tells if you a key is hit, without waiting; you can use it in a wait loop or for any other purpose, so it's a more general solution. A solution without O_NONBLOCK will wait until a key is hit - OK for this question but less generally useful.
Vinay Sajip
+1  A: 
system("pause");

will output "Press any key to continue..." and obviously, wait for any key to be pressed. I hope thats what you meant

I think the problem was that he doesn't use windows.
Lucas