In Windows (7), readChar(stdin) does not return until Enter is pressed. It then returns the first character typed.
var c = readChar(stdin)
echo c
output:
iasdfasdfasdf <- pressed enter after several keystrokes
i <- result echo()'d out
using on an open()'d file works as expected
var aFile = open("example.csv")
var c = readChar(aFile)
echo c
close(aFile)
output:
g
echo readChar(stdin) readChar(stdin) readChar(stdin) readChar(stdin)
Then it would wait for enter press once and print first four characters - or if you provided less than four, it would stop and wait for next line. For waiting for keypress, and not a line of input, you should look for another function.
Actually, if you were willing, a good addition to that module would be a procedure that reads a line from stdin without echoing (like, for password input)
Yes, something like getpass in python: https://github.com/python-git/python/blob/master/Lib/getpass.py
A translation of the python code. Works on linux, haven't tested on Windows.
when defined(windows):
proc getch(): cint {.header: "<conio.h>", importc: "_getch".}
proc putch(c: cint) {.header: "<conio.h>", importc: "_putch".}
else:
type
Termios = object
iflag, oflag, cflag, lflag: cint
line: char
cc: array[32, char]
ispeed, ospeed: cint
const
TCSANOW = 0.cint
TCSADRAIN = 1.cint
TCSAFLUSH = 2.cint
ECHO = 8.cint
proc tcgetattr(fd: cint, term: ptr Termios): cint
{.header: "<termios.h>", importc: "tcgetattr".}
proc tcsetattr(fd, optional_actions: cint, term: ptr Termios): cint
{.header: "<termios.h>", importc: "tcsetattr".}
proc getPassword(prompt: string): string =
when defined(windows):
result = ""
var c: char
echo prompt
while true:
c = getch()
case c
of '\r', chr(0xA):
break
of '\b':
result.setLen(result.len - 1)
else:
result.add(c)
else:
var cur, old: Termios
discard tcgetattr(0.cint, cur.addr)
old = cur
cur.lflag = cur.lflag and not ECHO
discard tcsetattr(0.cint, TCSADRAIN, cur.addr)
echo prompt
result = stdin.readLine()
discard tcsetattr(0.cint, TCSADRAIN, old.addr)
when isMainModule:
var pass = getPassword("What is the password? ")
echo "The password is: ", pass
proc getPasswordStars(prompt: string): string =
when defined(windows):
result = ""
var c: char
echo prompt
while true:
c = getch().char
case c
of '\r', chr(0xA):
putch(c.cint)
putch(0xD)
break
of '\b':
result.setLen(result.len - 1)
putch(c.cint)
putch(0x20)
putch(c.cint)
else:
result.add(c)
putch('*'.cint)
@def: that's fine with me
It looks like some of the constants are wrong, ECHO should be 8, not 10. The constants in the C header with a leading 0 are octal.