Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

function similar to getchar

Is there a Go function similar to C's getchar able to handle tab press in console? I want to make some sort of completion in my console app.

like image 382
demi Avatar asked Dec 30 '12 20:12

demi


People also ask

What can I use instead of Getchar in C?

As we can see, when we execute the above program, it takes a single character or group of characters using the scanf() library function instead of the getchar() function.

What is getchar and putchar?

putchar() function is a file handling function in C programming language which is used to write a character on standard output/screen. getchar() function is used to get/read a character from keyboard input. Please find below the description and syntax for above file handling function. File operation.

What is the difference between Gets and Getchar?

gets() reads from stdin until an end of line or end of file is reached. getchar() reads a single character from stdin. Since gets() does not check if there is space for the line being read in the pointer it is passed, it is generally considered unsafe.

What does getchar () do in C?

getchar is a function in C programming language that reads a single character from the standard input stream stdin, regardless of what it is, and returns it to the program. It is specified in ANSI-C and is the most basic input function in C.


2 Answers

C's getchar() example:

#include <stdio.h> void main() {     char ch;     ch = getchar();     printf("Input Char Is :%c",ch); } 

Go equivalent:

package main  import (     "bufio"     "fmt"     "os" )  func main() {      reader := bufio.NewReader(os.Stdin)     input, _ := reader.ReadString('\n')      fmt.Printf("Input Char Is : %v", string([]byte(input)[0]))      // fmt.Printf("You entered: %v", []byte(input)) } 

The last commented line just shows that when you press tab the first element is U+0009 ('CHARACTER TABULATION').

However for your needs (detecting tab) C's getchar() is not suitable as it requires the user to hit enter. What you need is something like ncurses' getch()/ readline/ jLine as mentioned by @miku. With these, you actually wait for a single keystroke.

So you have multiple options:

  1. Use ncurses / readline binding, for example https://code.google.com/p/goncurses/ or equivalent like https://github.com/nsf/termbox

  2. Roll your own see http://play.golang.org/p/plwBIIYiqG for starting point

  3. use os.Exec to run stty or jLine.

refs:

https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/zhBE5MH4n-Q

https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/S9AO_kHktiY

https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/icMfYF8wJCk

like image 117
rputikar Avatar answered Oct 09 '22 01:10

rputikar


Assuming that you want unbuffered input (without having to hit enter), this does the job on UNIX systems:

package main  import (     "fmt"     "os"     "os/exec" )  func main() {     // disable input buffering     exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()     // do not display entered characters on the screen     exec.Command("stty", "-F", "/dev/tty", "-echo").Run()     // restore the echoing state when exiting     defer exec.Command("stty", "-F", "/dev/tty", "echo").Run()      var b []byte = make([]byte, 1)     for {         os.Stdin.Read(b)         fmt.Println("I got the byte", b, "("+string(b)+")")     } } 
like image 41
blinry Avatar answered Oct 09 '22 00:10

blinry