0

I have the following code.

import lib

var stat = false

when isMainModule:
  while stat != true:
    echo("Option: ")
    var opt = readChar(stdin)
    case opt
      of 'q':
        stat = true
      of 'n':
        echo("Salu: ")
        var ss = readLine(stdin)
        echo("Nam: ")
        var nn = readLine(stdin)
        let k = prompt("Rust")
      else: discard

What I am trying to achieve is, prompting and receiving user input one after another for two variables. Upon choosing n I am expecting Salu first and once user input is supplied then Nam.

However, what I receive when I execute the following nim code by issuing the following command is, nim c -r src/mycode.nim

~~> nim c -r src/cmdparsing.nim
...
...
...
CC: stdlib_system.nim
CC: cmdparsing.nim
Hint:  [Link]
Hint: operation successful (48441 lines compiled; 2.338 sec total; 66.824MiB peakmem; Debug Build) [SuccessX]
Hint: /home/XXXXX/Development/nim_devel/mycode/src/mycode  [Exec]
Option: 
n
Salu: 
Nam:

Salu is being echoed, but readLine doesn't wait for my input and immediately echoes Nam. But, stacked readLine commands from the prompt procedure appears one after the other for receiving user input.

I was wondering what is that I am missing to understand here. Could someone enlighten me?

Code for prompt lives in lib.nim which is as follows,

proc prompt*(name: string): bool =
  echo("Salutation: ")
  var nn = readLine(stdin)
  echo(nn&"."&name)
  echo("Diesel")
  var dd = readLine(stdin)
  echo(dd)
  return true
Bussller
  • 1,961
  • 6
  • 36
  • 50

1 Answers1

2

You do a readChar to get the opt value, and then you input two chars: n and \n. The first is the opt value, the second gets buffered or retained in the stdin waiting for further reading. The next time you try to read a line, the \n that's still hanging is interpreted as a new line, and immediately assigned to ss. You don't see anything because the line is empty except for the newline char.

E.g.

var opt = readChar(stdin)

case opt
of 'n':
  var ss = readLine(stdin)
  echo ss
else:
  discard

Compile and run, but in the input write something like "ntest". n fires the first branch of case, test (the remainder of stdin) is assigned to ss, and echoed.

You have two options to solve the problem:

  1. Read a line instead of a char, and store only the first char with something like var opt = readLine(stdin)[0].

  2. Use the rdstdin module:

    import rdstdin
    
    var ss = readLineFromStdin("Salu:")
    
xbello
  • 7,223
  • 3
  • 28
  • 41