Read a character from standard input (without pressing Enter)

3,060 views
Skip to first unread message

__kaveh__

unread,
Mar 1, 2013, 9:29:18 AM3/1/13
to golan...@googlegroups.com
I want my app shows:

press any key to exit ...

And when I press any key, it exits; something like Console.ReadKey() in C#.

I have googled for it but all cases that I've found needed to press enter anyway.

Mateusz Czapliński

unread,
Mar 1, 2013, 9:46:35 AM3/1/13
to golan...@googlegroups.com

As far as I know, there is no such function in Go standard library, and I don't know of any cross-platform "pure-Go" implementation in any other publicly available package; if you accept using cgo, you might try to using some curses/ncurses bindings for Go, or maybe some SDL bindings.

This behaviour must be implemented in OS-dependent way; other than cgo, I could suggest:
  a) [easier] write "Press ENTER to exit..." instead, and use existing functions, or:
  b) [harder] look how Console.ReadKey() is implemented in Mono, or crt module in FreePascal, and try to translate this to Go using the syscall package, for as many OS platforms as you need.

/M.

ron minnich

unread,
Mar 1, 2013, 11:18:25 AM3/1/13
to Mateusz Czapliński, golan...@googlegroups.com
here's how I got to raw mode in gocpu, hope this has some use for you.

package main

/*
#include <stdlib.h>
#include <pty.h>
#include <utmp.h>
#include <curses.h>
#cgo LDFLAGS: -lutil -lcurses
*/
import "C"

import (
"fmt"
"io"
"log"
"net"
"os"
)

func client() {
go runufs()
addrstring := fmt.Sprintf("%v\n", *addr)
fmt.Printf("serving 9p on %v\n", *addr)
c, err := net.Dial("tcp", *listenaddr)
if err != nil {
log.Fatal(err)
}
c.Write([]byte(addrstring))

C.initscr()
C.raw()

go io.Copy(c, os.Stdout)
io.Copy(os.Stdin, c)
C.endwin()
}

Hotei

unread,
Mar 1, 2013, 2:07:09 PM3/1/13
to golan...@googlegroups.com
I wrote a function for that a while back but it was a hack.  Ubuntu so I used :
fmt.Printf("Hit ANY key to exit: ")
cmd := exec.Command("/bin/stty", "-F", "/dev/tty", "-icanon", "min", "1") // worked ok

after setting raw mode you can :

var keybuf [1]byte
_, _ = os.Stdin.Read(keybuf[0:1])

A problem I had was that on exit the console is still in raw mode, so it needs to be reset with stty every time.  It wasn't a 
problem for me but your mileage may vary.  This was well originally written way before Go1 but assuming you're in a *nix environment you should be able to use something like it.
Message has been deleted
Message has been deleted
Message has been deleted

emanuele...@gmail.com

unread,
Oct 25, 2015, 4:31:17 PM10/25/15
to golang-nuts
If you are on Windows OS you can use my library to get keystrokes from keyboard:

Reply all
Reply to author
Forward
0 new messages