Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

How can I read a single character from a file? From the keyboard?

by faq_monk (Initiate)
on Oct 13, 1999 at 03:42 UTC ( #812=perlfaq nodetype: print w/replies, xml ) Need Help??

Current Perl documentation can be found at perldoc.perl.org.

Here is our local, out-dated (pre-5.6) version:

You can use the builtin perlfunc:getc function for most filehandles, but it won't (easily) work on a terminal device. For STDIN, either use the Term::ReadKey module from CPAN, or use the sample code in perlfunc:getc.

If your system supports POSIX, you can use the following code, which you'll note turns off echo processing as well.

    #!/usr/bin/perl -w
    use strict;
    $| = 1;
    for (1..4) {
        my $got;
        print "gimme: ";
        $got = getone();
        print "--> $got\n";
    }
    exit;

    BEGIN {
        use POSIX qw(:termios_h);

        my ($term, $oterm, $echo, $noecho, $fd_stdin);

        $fd_stdin = fileno(STDIN);

        $term     = POSIX::Termios->new();
        $term->getattr($fd_stdin);
        $oterm     = $term->getlflag();

        $echo     = ECHO | ECHOK | ICANON;
        $noecho   = $oterm & ~$echo;

        sub cbreak {
            $term->setlflag($noecho);
            $term->setcc(VTIME, 1);
            $term->setattr($fd_stdin, TCSANOW);
        }

        sub cooked {
            $term->setlflag($oterm);
            $term->setcc(VTIME, 0);
            $term->setattr($fd_stdin, TCSANOW);
        }

        sub getone {
            my $key = '';
            cbreak();
            sysread(STDIN, $key, 1);
            cooked();
            return $key;
        }

    }

    END { cooked() }

The Term::ReadKey module from CPAN may be easier to use:

    use Term::ReadKey;
    open(TTY, "</dev/tty");
    print "Gimme a char: ";
    ReadMode "raw";
    $key = ReadKey 0, *TTY;
    ReadMode "normal";
    printf "\nYou said %s, char number %03d\n",
        $key, ord $key;

For DOS systems, Dan Carson <dbc@tc.fluke.COM> reports the following:

To put the PC in ``raw'' mode, use ioctl with some magic numbers gleaned from msdos.c (Perl source file) and Ralf Brown's interrupt list (comes across the net every so often):

    $old_ioctl = ioctl(STDIN,0,0);     # Gets device info
    $old_ioctl &= 0xff;
    ioctl(STDIN,1,$old_ioctl | 32);    # Writes it back, setting bit 5

Then to read a single character:

    sysread(STDIN,$c,1);               # Read a single character

And to put the PC back to ``cooked'' mode:

    ioctl(STDIN,1,$old_ioctl);         # Sets it back to cooked mode.

So now you have $c. If ord($c) == 0, you have a two byte code, which means you hit a special key. Read another byte with perlfunc:sysread, and that value tells you what combination it was according to this table:

    # PC 2-byte keycodes = ^@ + the following:

    # HEX     KEYS
    # ---     ----
    # 0F      SHF TAB
    # 10-19   ALT QWERTYUIOP
    # 1E-26   ALT ASDFGHJKL
    # 2C-32   ALT ZXCVBNM
    # 3B-44   F1-F10
    # 47-49   HOME,UP,PgUp
    # 4B      LEFT
    # 4D      RIGHT
    # 4F-53   END,DOWN,PgDn,Ins,Del
    # 54-5D   SHF F1-F10
    # 5E-67   CTR F1-F10
    # 68-71   ALT F1-F10
    # 73-77   CTR LEFT,RIGHT,END,PgDn,HOME
    # 78-83   ALT 1234567890-=
    # 84      CTR PgUp

This is all trial and error I did a long time ago, I hope I'm reading the file that worked.

Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
[erix]: (eh, I meant the single-slit experiment)
[james28909]: what if our whole universe is the result of someoneviewing the big bang before it happened? and BANG, wave function collapses and all that matter comes out and creates the universe
[james28909]: who knows though
[holli]: There is a book called "Cosm" in which something like that happens. A particle accelerator accident creates a new universe in which time goes superfast
[erix]: tall story, jim
[james28909]: " I'd even let him grab my mums pussy if that helps :-D" im dead xD
[holli]: clicky
[shmem]: "universe in which time goes superfast" - hmm, light behaves like syrup there, I guess
erix chuckles at the existence of a nebula award
[holli]: relative to ours.

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (16)
As of 2017-12-15 16:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What programming language do you hate the most?




















    Results (436 votes). Check out past polls.

    Notices?