0

I'm working on a project where I need to take an input from the user and then cut it up into its individual characters for later use (to shift them up one character) but I'm having trouble getting the input into an array and printing it out to check that its in there. Currently my code is

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $count=0;      # this block just creates variables
my $userinput;

print "Input?";      
$userinput=<STDIN>;   # this block just gets input and creates the array
my @userarray=();

while(<@userarray>) {
@userarray = split('', $userinput);   #this block should loop as many times as there are characters in the input while separating the characters
}

print Dumper(@userarray);   #this should print the array

My output should look some like this if their input is "house"

@userarray[0]= "h"
@userarray[1]= "o"
@userarray[2]= "u"
@userarray[3]= "s"
@userarray[4]= "e"

But when I do enter something in it just print back a blank screen despite strict and warnings not coming back with anything. Where did I go wrong?

masral
  • 69
  • 5
  • 4
    `while(<@userarray>)` on an empty array looks problematic – zzxyz Apr 23 '18 at 23:11
  • 1
    You need to assign `@userarray` _outside_ the loop – Matt Jacob Apr 23 '18 at 23:27
  • 1
    @MattJacob It's a split..no loop required at all, right? – zzxyz Apr 23 '18 at 23:28
  • 1
    @zzxyz Sure, but the OP implied that he/she wanted to iterate over each character individually for some reason. But I agree... the `split` only needs to be done once (and probably without obscuring the fact that the first parameter is a regex) – Matt Jacob Apr 23 '18 at 23:30
  • I removed the loop, it works like a charm now – masral Apr 23 '18 at 23:30
  • Unicode text processing advice: splitting into individual characters is almost always not useful. [Split into graphemes instead](http://p3rl.org/perlrebackslash.html#\X): `perl -Mutf8 -C -E'say for split /\b{gcb}/, "crème brûlée"'` – daxim Apr 24 '18 at 07:33

2 Answers2

4

<D> reads and returns one (the next) record (that's a line if the record separator $/ hasn't been changed) from the file handle D in scalar context. In list context all remaining records are returned (as an array).

Said that, this section is the problem:

$userinput=<STDIN>;   # this block just gets input and creates the array
my @userarray=();

while(<@userarray>) {
@userarray = split('', $userinput);   #this block should loop as many times as there are characters in the input while separating the characters
}

<@userarray> returns nothing as @userarray sure isn't a valid file handle. So that loop is never entered.

If you want the user to input only one line, don't use the loop at all. Read one line and split it.

$userinput=<STDIN>;   # this block just gets input and creates the array
chomp($userinput);
my @userarray=();

@userarray = split('', $userinput);

But that loop may indicate, that you want the user to be able to enter more than one line. If so, loop until there's no input left (EOF), reading the input line by line. Split the line and push the result into your array.

while(my $line = <STDIN>) {
  chomp($line);
  push(@userarray, split('', $line));
  print(join(',', @userarray) . "\n");
}

For both ways: chomp() removes the trailing record separator (new line) at the end of the record (line). Don't use it, if you want to keep these. I assumed you don't.

sticky bit
  • 36,626
  • 12
  • 31
  • 42
1

This is a common Perl pattern. You want to loop so the user can enter more data. Try something like this:

print "Input?";
while (my $userinput = <STDIN>) {
  chomp $userinput; # remove trailing newline
  my @userarray = split //, $userinput; 
  print Dumper(\@userarray);
}
mwp
  • 8,217
  • 20
  • 26