For Programmers: Free Programming Magazines  


Home > Archive > PERL Miscellaneous > September 2006 > Reading from standard input









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Reading from standard input
Harpreet

2006-09-26, 8:03 am

Hi.

I am learning perl scripting and was reading an online tutorial where i
encountered this code(at the end of message). The first part of the
code (reading from file) has been pasted as-is and the second(reading
from standard input stream) was written by me. When I execute the
program, I get the correct result from the first one and then I type
into the stream some data but I don't know how to end it. I used the
conventional unix "dot-enter" scheme but it didn't work. Neither did
Ctrl-D. I found some examples which read from <STDIN> and worked with a
while loop. Can somebody explain me why reading from the standard input
doesn't work the way I have written ? If I am missing the escape
character to denote the end of stream, please mention it.

Any pointers will be appreciated.

Thanks and Regards,

Harpreet.


<CODE>
#!usr/local/bin/perl
#

$file = '/etc/passwd'; # Name the file
open(INFO, $file); # Open the file
@lines = <INFO>; # Read it into an array
close(INFO); # Close the file
print @lines; # Print the array

open(INFO, '-');
@lines2 = <INFO>; # Read it into an array
close(INFO);
print @lines2;
</CODE>

Michele Dondi

2006-09-26, 6:59 pm

On 26 Sep 2006 07:01:57 -0700, "Harpreet" <harpreet.saluja@gmail.com>
wrote:

>Subject: Reading from standard input


<STDIN>

>I am learning perl scripting and was reading an online tutorial where i

^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^

Ouch! I smell... well, something bad...

>encountered this code(at the end of message). The first part of the
>code (reading from file) has been pasted as-is and the second(reading
>from standard input stream) was written by me. When I execute the
>program, I get the correct result from the first one and then I type
>into the stream some data but I don't know how to end it. I used the


^D

>conventional unix "dot-enter" scheme but it didn't work. Neither did


What is it?!?

>Ctrl-D. I found some examples which read from <STDIN> and worked with a
>while loop. Can somebody explain me why reading from the standard input


Indeed that would be the "canonical" way to read line by line...

>#!usr/local/bin/perl


(please do a favour to yourself and have perl you give all the help it
can give to avoid common mistakes, so)

use strict;
use warnings;

>$file = '/etc/passwd'; # Name the file


my $file = '/etc/passwd';
# Do you really want to play with *that* file?

>open(INFO, $file); # Open the file


open my $info, '<', $file or die "Can't open `$file': $!\n";

>@lines = <INFO>; # Read it into an array
>close(INFO); # Close the file
>print @lines; # Print the array


As above, if there's no real need to slurp in all the file at once,
don't. Use a while loop instead:

print while <INFO>;
# or
print while <$info>;

>open(INFO, '-');


You don't need that. You already have STDIN.

>@lines2 = <INFO>; # Read it into an array


My first guess was that reading from STDIN in list context would
return the lines available at the moment of the call and that that
would explain your problem. But indeed I made an experiment and for me
it works as expected:

$ perl -MFatal=open -MData::Dumper -e 'open I,"-";
> chomp(@a=<I> ); print Dumper \@a'

foor
baar
bazz
$VAR1 = [
'foor',
'baar',
'bazz'
];

I just pressed ^D here.


HTH,
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
John W. Krahn

2006-09-26, 6:59 pm

Harpreet wrote:
>
> I am learning perl scripting and was reading an online tutorial where i
> encountered this code(at the end of message). The first part of the
> code (reading from file) has been pasted as-is and the second(reading
> from standard input stream) was written by me. When I execute the
> program, I get the correct result from the first one and then I type
> into the stream some data but I don't know how to end it. I used the
> conventional unix "dot-enter" scheme but it didn't work. Neither did
> Ctrl-D. I found some examples which read from <STDIN> and worked with a
> while loop. Can somebody explain me why reading from the standard input
> doesn't work the way I have written ?


Because you are not reading from the standard input.

> If I am missing the escape
> character to denote the end of stream, please mention it.
>
> Any pointers will be appreciated.
>
>
> <CODE>
> #!usr/local/bin/perl


You are using a relative path when you should be using an absolute path:

#!/usr/local/bin/perl

And don't forget:

use warnings;
use strict;


> $file = '/etc/passwd'; # Name the file
> open(INFO, $file); # Open the file


You should *ALWAYS* verify that the file opened correctly:

open(INFO, $file) or die "Cannot open '$file' $!";

> @lines = <INFO>; # Read it into an array
> close(INFO); # Close the file
> print @lines; # Print the array
>
> open(INFO, '-');


You should *ALWAYS* verify that the file opened correctly:

open(INFO, '-') or die "Cannot open '-' $!";

You are trying to open the file '-', standard input is not involved when
opening a plain file.

The *only* time that '-' has anything to do with standard input is when @ARGV
and <> are used:

local @ARGV = '-';

while ( <> ) { # read from STDIN because @ARGV contains '-'
print;
}

> @lines2 = <INFO>; # Read it into an array
> close(INFO);
> print @lines2;
> </CODE>




John
--
use Perl;
program
fulfillment
Ted Zlatanov

2006-09-26, 6:59 pm

On 26 Sep 2006, harpreet.saluja@gmail.com wrote:

> When I execute the program, I get the correct result from the first
> one and then I type into the stream some data but I don't know how
> to end it. I used the conventional unix "dot-enter" scheme but it
> didn't work. Neither did Ctrl-D. I found some examples which read
> from <STDIN> and worked with a while loop. Can somebody explain me
> why reading from the standard input doesn't work the way I have
> written ? If I am missing the escape character to denote the end of
> stream, please mention it.


You may be on a Windows or DOS system, where Ctrl-Z is the end of file
character, not Ctrl-D as in other systems. Try that.

Ted
Harpreet

2006-09-27, 4:00 am

Thanks John ! I finally understood the concept of '-' stream.

Harpreet

John W. Krahn wrote:
> Harpreet wrote:
>
> Because you are not reading from the standard input.
>
>
> You are using a relative path when you should be using an absolute path:
>
> #!/usr/local/bin/perl
>
> And don't forget:
>
> use warnings;
> use strict;
>
>
>
> You should *ALWAYS* verify that the file opened correctly:
>
> open(INFO, $file) or die "Cannot open '$file' $!";
>
>
> You should *ALWAYS* verify that the file opened correctly:
>
> open(INFO, '-') or die "Cannot open '-' $!";
>
> You are trying to open the file '-', standard input is not involved when
> opening a plain file.
>
> The *only* time that '-' has anything to do with standard input is when @ARGV
> and <> are used:
>
> local @ARGV = '-';
>
> while ( <> ) { # read from STDIN because @ARGV contains '-'
> print;
> }
>
>
>
>
> John
> --
> use Perl;
> program
> fulfillment


Michele Dondi

2006-09-27, 4:00 am

(I don't have John's post so I'm replying to you)

On 26 Sep 2006 21:40:18 -0700, "Harpreet" <harpreet.saluja@gmail.com>
wrote:
[color=darkred]

I thought so too. But that is *not* the case, and the docs confirm
that:

: In the 2-arguments (and 1-argument) form opening '-' opens STDIN
: and opening '>-' opens STDOUT.

Yet, not a particularly good reason to use it, especially when you
already have STDIN.


Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
John W. Krahn

2006-09-27, 9:58 pm

Michele Dondi wrote:
> (I don't have John's post so I'm replying to you)


That is because I cancelled it when I realised that I was wrong. :-)


John
--
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order. -- Larry Wall
Harpreet

2006-09-29, 3:59 am

Hi Michele,

I didn't understand what you said earlier but I experimented with the
code you had posted and it works exactly the way I wanted. But since I
have just started exploring perl, things like Mfatal and Mdata don't
make much sense to me. I hope to read all that in due time and
understand what you said. Do you have a good soft document or pointer
to an online resource through which I can learn perl.

regards,

Harpreet


Michele Dondi wrote:
> (I don't have John's post so I'm replying to you)
>
> On 26 Sep 2006 21:40:18 -0700, "Harpreet" <harpreet.saluja@gmail.com>
> wrote:
>
>
> I thought so too. But that is *not* the case, and the docs confirm
> that:
>
> : In the 2-arguments (and 1-argument) form opening '-' opens STDIN
> : and opening '>-' opens STDOUT.
>
> Yet, not a particularly good reason to use it, especially when you
> already have STDIN.
>
>
> Michele
> --
> {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
> (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
> .'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
> 256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,


Michele Dondi

2006-09-29, 7:59 am

On 29 Sep 2006 00:13:44 -0700, "Harpreet" <harpreet.saluja@gmail.com>
wrote:

>I didn't understand what you said earlier but I experimented with the
>code you had posted and it works exactly the way I wanted. But since I
>have just started exploring perl, things like Mfatal and Mdata don't


Caveat: there are *no* things like "Mfatal and Mdata", since for one
thing capitalization does matter and the second module is
Data::Dumper.

Here I'm making use of the -M command line switch. Learn more about
it, and all the other ones reading

perldoc perlrun

Basically it's a shortcut for use()ing modules. In a "regular" script,
as opposed to a one-liner you would write:

use Fatal 'open';

It's a module designed to make certain operations cause the script to
die with an informative message in case they fail. This was not
strictly required in a one-liner, but I also (like another poster) had
erroneusly thought that

open F, '-';

would try open()ing a file named '-' in the cwd. So I used that as a
"workaround" for not having to explicitly check the return value of
open() and report something significative accordingly.

Similarly, Data::Dumper is a module giving you "stringified perl data
structures". It's handy to inspect some variables, like I did here for
a certain array. Indeed in many cases

print "@a";

would suffice. But in other ones, especially when you actually have
complex data structures, D::D is much better if not absolutely
necessary. (Although then there are other modules with similar
functionality.)

To learn more about these two modules you can check their
documentation:

perldoc Fatal
perldoc Data::Dumper

>make much sense to me. I hope to read all that in due time and
>understand what you said. Do you have a good soft document or pointer
>to an online resource through which I can learn perl.


I can point you to a good document that *you* have: it's already in
your system and you can reach it with the perldoc program, as you may
have inferred from the above. Indeed perl comes with extensive
documentation. As a starter, you {may,should} look into

perldoc perl
perldoc perldoc

to know about core Perl documentation and perldoc's self
functionality: the latter is much and can be substituted by man (if
you're under *NIX) for regular modules, but it can do much more: in
particular give you documentation about single functions and search
the FAQ for you.


HTH,
Michele
--
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com