Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

How can I get just one character from STDIN?

( #63680=categorized question: print w/ replies, xml ) Need Help??
Contributed by Anonymous Monk on Mar 12, 2001 at 02:49 UTC
Q&A  > input and output


I want to capture a single character like the C function getch(). $ch = <STDIN> and $ch = getc() don't return until the user enters a trailing newline. What method(s) are available for this?

Answer: How can I get just one character from STDIN?
contributed by fizbin

The basic problem is that the terminal device driver doesn't consider a read to have happened until the user presses a return character - this means that no program is going to be able to read a single character unless they first tell the device driver: "Behave differently, and consider a read complete after a single character".

Hence the suggestion to use Term::ReadKey - it tells the device to behave differently. At a C level, you'd use tcsetattr out of the termios function set. If for some reason you don't think that your deployment environment will have Term::ReadKey installed, you could try a system call to stty; "stty cbreak" will enter the one-character-at-a-time mode and "stty icanon" will take you back. (see stty's man page)

By the way, on Win32 the way I'd approach this is though the InputChar function inside Win32::Console.

Answer: is ther any way to get only one char from stdin
contributed by AgentM

use Curses; ...#initialization stuff my $char=getch();
Read more on Curses in your local man pages for more terminal manipulation goodness.
Answer: is ther any way to get only one char from stdin
contributed by crazyinsomniac

Very interesting solutions, i'd just use Term::Readkey.

Answer: How can I get just one character from STDIN?
contributed by teleron

Use Term::ReadKey. Set Readmode 'cbreak'. I use it if I am in a loop and need to get out by pressing a key.

Answer: is ther any way to get only one char from stdin
contributed by Caillte

Another way is:

$buf = ' '; while($buf) { sysread STDIN, $buf, 1; print "$buf\n" # or whatever else you want # to do with it ;) }

I've tested this out on linux and it works fine. Any reason why it wouldnt work on other platforms?

Editor: The problem with this method is that the sysread will hang until the user presses the RETURN key (so if the user really only enters one character and it isn't RETURN, then the program will just "hang").

Please (register and) log in if you wish to add an answer

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others drinking their drinks and smoking their pipes about the Monastery: (5)
    As of 2016-08-27 05:51 GMT
    Find Nodes?
      Voting Booth?
      The best thing I ever won in a lottery was:

      Results (378 votes). Check out past polls.