0

I'm new to PERL but have picked it up rather quickly as I work in C.

My question seems simple, but for the life of me I cant find a simple answer. Basically I want to print something on the same line as user input

Example

print "Please Enter Here: ";
my $input = <STDIN>;
chomp $input;
print " - You Entered: $input";

Output

Please Enter Here: 123
- You Entered: 123

This is undesired as I want all of this on one line in the terminal window. At the moment it prints the second string on the line below once the user has pressed the enter key. I guess what i'm going to need to do is something with STDIN like ignore the carriage return or newline but I'm not sure.

Desired Output

Please Enter Here: 123 - You Entered: 123

I don't know why this seems to be a complicated thing to google but I just haven't fathomed it, so any help would be appreciated.

Ta

kesmosis
  • 3
  • 3
  • 1
    STDIN is line based. Probably you need other functions to do this. For example: http://stackoverflow.com/questions/8676026/how-can-i-have-perl-take-input-from-stdin-one-character-at-a-time – Lajos Veres Mar 12 '14 at 11:35
  • 1
    Why not just redraw the interface after input is taken? Otherwise you will need to find some way for your terminal to ignore all characters except newline, which is bound to be a pain in the behind. – TLP Mar 12 '14 at 11:38
  • surely theres a simple way of just ignoring the return line when the user presses the enter key. in the same way chomp removes \n from the end of a variable, is there a way to do the same thing to STDIN so that it doesn't go to a new line? – kesmosis Mar 12 '14 at 11:47
  • Hmm, i may be making an idiot out of me here, but i always thought that linebreak came from the enter that the user actually entered? If that was true, you would at least need your user to end the input with something else or have the terminal not draw the newline before passing it to the application. Might be stupid though, i really never thought about this. – DeVadder Mar 12 '14 at 11:54

2 Answers2

2

Well, this is interesting...

First, you'd have to turn off terminal echoing, using something like IO::Stty. Once you do that, you could use getc. Note that the getc perldoc page has a sample program that could be used. You can loop until you get a \n character as input.

You can also try Term::ReadKey.

I have never done this myself. I'll have to give it a try, and if I succeed, I'll post the answer.


The Program

Ended up I already had Term::ReadKey installed:

#! /usr/bin/env perl
#
use warnings;
use strict;
use feature qw(say);

use Term::ReadKey;

ReadMode 5;  # Super Raw mode

my $string;

print "Please Enter Here: ";
while ( my $char = getc ) {
    last if ord( $char ) < 32;  # \r? \n? \l?
    $string .= $char;
    print "$char";
}

ReadMode 0;
say qq( - You entered "$string".);

I realized that, depending how the terminal is setup, it's hard to know exactly what is returned when you press <RETURN>. Therefore, I punted and look for any ASCII character that's before a space.


One more thing: I didn't handle what happens if the user hit a backspace, or other special characters. Instead, I simply punt which may not be what you want to do.

Community
  • 1
  • 1
David W.
  • 105,218
  • 39
  • 216
  • 337
-1

In the end I did:

"\033[1A\033[45C

It uses the code functions for line up and 45 indent and it works. Thanks for all the help though.

kesmosis
  • 3
  • 3