http://www.perlmonks.org?node_id=127219


in reply to I'm so confused

st4k,
The problem is the way you have your data entered into the files. I can tell that your files look like this:
file1:    file2:    file3:
one\n     four\n    seven\n
two\n     five\n    eight\n
three^Z   six^Z     nine^Z
The ^Z represent the end of file character. So that when you dump the array using:
print @out;
There are no line breaks between three-four and six-seven. To correct this you should chomp each read and store all the data without newlines:
for (my $i = 0; $i < $num; $i++) { print "$ARGV[$i]\n"; open (FH, "$ARGV[$i]") || die "Cant open: $!"; while (<FH>) { chomp; ## <- added this line push @out, lc; } close FH || die "Cant open: $!"; }
To print this as you would expect, use this instead:
print join (@out,"\n");
This tells print to make one long string with a newline inserted between each element of @out.

Hope this helps.

--Jim

Replies are listed 'Best First'.
Re: Re: I'm so confused
by st4k (Novice) on Nov 24, 2001 at 08:13 UTC
    This place rocks! I didnt expect such prompt replies :-)
    The thing is I want each element in the array to be seperated by newlines so that when the script outputs the final list it will be nice and orderly, one word per line.
    What the script does is read from @argv some files that it will read into an array, lowercase, sort, remove dups (not done yet) and then output the final array to out.txt
    Is there a way to "unchomp" an array making sure that each element has a newline (but not add one if it already does) or something like that?
    Thanks to everyone who replied
    Im reading also while Im trying everyones ideas
    #!/usr/bin/perl use strict; use warnings; use diagnostics; my @out; my $num = scalar(@ARGV); if (-e "out.txt"){ print "Please move or rename out.txt\n"; exit 0; } for (my $i = 0; $i < $num; $i++) { open (FH, "$ARGV[$i]") || die "Cant open: $!"; while (<FH>) { push (@out, lc); } close FH || die "Cant close: $!"; } print sort @out
      You might want to be using the <> operator here. <> reads from the files passed in ARGV (if they exist) or from STDIN otherwise. This means that you can have this behaviour with no extra effort if you want it in the future.

      It'll certainly save you from having to worry about opening each of those files and the like. So your code could simplify to:

      #!/usr/bin/perl -w use strict; use diagnostics; if(-e "out.txt") { # complain about file. } my @out; while(<>) { chomp; push @out, lc($_); } # do stuff with @out: @out = sort @out; # print it (to STDOUT for the moment) print join("\n", @out);
      I agree with everyone else here, that you probably don't want to be inserting the newline until you're ready to output the data. If you decide, for some reason, later to reverse all the characters on each of your lines or some such, that newline character can get in the way.

      Good luck.

      Generally speaking, you're not going to want new lines in your actual data. That may not always be the case, but if you're going to work with what's in the array, the new line char might get in the way. The best way (in my opinion), would be to chomp off the new line char, and then when you output it, print new lines. There's several ways to do that. The easiest way would be to take the array and join all elements together with new lines. like so..
      print join "\n", @out;
      Hope that helps,
      Rich
      Hey the join function works but not in the way I expected it to work.
      print join "\n", @out;
      works just fine and inserts the newline seperator just like I want it to do while
      join "\n", @out;
      print @out;
      returns the chompd output
      the solution I figured out was
      @out = join "\n", @out;
      print @out;
      Is this the correct way to do this? Im trying to be as strict as possible and learn perl without using cheats and workarounds if you know what I mean. If I get the hang of properly structured programming I think it can cary over to whatever language I learn in the future. THANKS AGAIN EVERYONE!
        st4k, as rchiav stated and as I showed you earlier, you probably don't want to store the newline characters in your array. In my example using print join("\n",@out); I demonstrated a way to manipulate the array (without changing its contents) and printing the results each element on a new line. By storing the data without newlines you could also do something slightly different:
        my @out = qw(one two three four five six seven eight nine); my $i = 0; foreach (@out) { print "\$out[",$i++,"] = '$_'\n"; } =output= $out[0] = 'one' $out[1] = 'two' $out[2] = 'three' $out[3] = 'four' $out[4] = 'five' $out[5] = 'six' $out[6] = 'seven' $out[7] = 'eight' $out[8] = 'nine'
        But if you had stored the newlines in the array, the last ' in each line would've been pushed to the next line by the newline character stored in the array:
        =output= $out[0] = 'one ' $out[1] = 'two ' $out[2] = 'three ' $out[3] = 'four ' $out[4] = 'five ' $out[5] = 'six ' $out[6] = 'seven ' $out[7] = 'eight ' $out[8] = 'nine '
        You have more flexibility if you store only the data.

        In your example @out = join "\n", @out; you are destroying your array. Instead of the output above you would get the following output using the same print loop:

        my @out = qw(one two three four five six seven eight nine); @out = join "\n", @out; my $i = 0; foreach (@out) { print "\$out[",$i++,"] = '$_'\n"; } =output= $out[0] = 'one two three four five six seven eight nine'
        Instead of having 9 rows you now have only one row made up of a string with interspersed newlines. As a rule, most people don't print an array using   print @array; except when debugging.

        Try playing around with the print loop above to test other types of array manipulation. It will give you a better idea of how your data is stored in the array structure.

        --Jim