Perl语言入门和提高05

Perl语言入门和提高05

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Spring, 2009 Spring, 2009 File Handling --- Standard Handles • Standard file handles (Already opened): Perl 入门和提高 data following __END__ input, can be redirected output, can be redirected output, can’t be redirected, for error messages • Write to file, “print” print STDERR $err_msg; print @lines; # default is STDOUT print FD $a, $b; # not print FD, $a … • Read file, the <FILEHANDLE>, diamond operator “<>” while($line = <STDIN>){}; # read one line @lines=<>; # read file listed in @ARGV # one by one, or read from STDIN – – – – Lesson 5 周晓方 courses@xfzhou.homeftp.org DATA STDIN STDOUT STDERR 1 Spring, 2009 5 File Handling --- User files "my", "local", and "our"(perl5.6+) • 字典作用域 my declares a lexical variable totally hidden from the outside world Spring, 2009 • Open a user file – 只用于当前作用域,不自动传递给所调用的子程序 – 可以模仿C语言的auto变量 – 要模仿C语言的static变量,可以这样写 – For read: – For write: – For append: – For pipe read: – For pipe write: { my($s) = 0; # 单独用一对{},在里面定义my变量和子程序 sub getnext { $s++; } } # $s对外不可见,但每次调用getnext之间都保留$s的值 print getnext; print getnext; print getnext; • 动态作用域 local open(FD, "<filename"); open(FD, ">filename"); open(FD, ">>filename"); open(FD, "process|"); open(FD, "|process"); – +> 截断文件并打开读写 – 自动传递给所调用的子程序 +< 不截断文件并打开读写 • Close file: close(FD); open(FD,"ls -la |"); print <FD>; • 全局作用域 our (perl5.6+) – use vars qw(变量列表),例use vars qw($frob @mung %seen); – 缺省情况下都是全局变量,可以用$v, $::v, 或$main::v引用 # DOS dir • $oldFD = select(FD); # choose a default output 6 2 Sample Spring, 2009 Sample • Find out the ed2k link in html files a(); our $x=7; our $y = 17; a(); sub a { my $x = 10; local $y = 5; print "ax$x, ay$y\n"; b(); } sub b { print "bx$x, by$y\n"; } ax10, ay5 bx, by5 ax10, ay5 bx7, by5 Spring, 2009 特征 <a href="ed2k://|file|%5B...S01EP01.FRTVS.rmvb|110711118|dc6cc75a e43d224f2ed77e4ae00228d0|h=VPJ7LDHO5R6ECOVFG2SYSS74O2ZMMKLT|/" ed2k="ed2k://|file|%5B%E... httpget http://www.verycd.com/topics/146912/ | perl xed2k.pl #!/usr/bin/perl; use strict; my @lines = grep /href=\"ed2k\:/, <>; chomp @lines; foreach (@lines) { $_ =~ s/.*ed2k\:/ed2k:/; $_ =~ s/\".*//; } print "$_\n" foreach @lines; 1; 想想如何将这 个脚本和电驴下载工具互动起来? 有字典变量x,有动态变量y,都是在a中定义的 没有全局、动态和字典变量x,有动态变量y(在a中定义的) 有字典变量x,有动态变量y,都是在a中定义的 有全局变量x(用our定义的),有动态变量y(在a中定义的) 7 3 Program Spring, 2009 Spring, 2009 Subroutine III——Prototype • Perl程序的一般结构(务必用my定义变量) #!/usr/local/bin/perl -w use strict; use lib "path"; use module_names; require "sourcefile"; … main code … sub routine1 {…} sub routine2 {…} sub routine3 {…} … 1; __END__ … pod usually starts here • sub name (prototype_format) {BLOCK} sub func1($) { …}#只接受一个标量参数的函数 sub func2($$;$){# 头两个参数是必须的,后一个是可选的 } 不带\的@和%必须放在最后,通吃后面的所有参数 sub mygrep(&@) # &代码 mygrep {/1+/} $a, $b sub myopen(*$) # *句柄 myopen HANDLE, $name sub mypush (\@@) { # \@ is array-ref my $list = shift; # \% is hash –ref, etc push @$list, @_; # @ is array, last one } sub pi () { 3.1416 } # constanct function print pi + 2; # print 5.1416, not 3.1416 # take it as print(pi(+2)) if not prototype 回家作业(附件 学号-No.4.pl) 1. 用级数展开sin(x) (x<pi) 2. 编写子程序sub mysin,第一 个参数是x,第二个参数是n, 返回sin(x)级数展开到第n项 3. 主程序调用mysin(1,$n),其 中$n=(0..10),显示每次计 算的结果,运行结果如下: 1 0.833333333333333 2 0.841666666666667 3 0.841468253968254 4 0.841471009700176 5 0.841470984648068 6 0.841470984808658 7 0.841470984807894 8 0.841470984807897 9 0.841470984807897 10 0.841470984807897 • 若用了函数原形,要在调用前就定义函数头 • 常数可以用use constant pi=>3.1415 更方便 4 – 这样定义的常数不用带前缀$,直接用pi 8 Spring, 2009 Spring, 2009 The UNIX fork( ) and exec( ) 使用函数原形的一个例子程序 #!/usr/bin/perl -w use strict; my(@list); sub pi_proto () {3.1416} sub pi_normal {3.1416} • fork() The only way to start a new process. • 运行结果 – Return child pid to parent, return 0 to child. – Copy all data sections. Code are usually shared. – File descriptors are shared. pi_proto + 2 is 5.1416 pi_normal + 2 is 3.1416 list is (1, 2, 3, 4) • exec(str) loads a new image (code), never return. sub mypush (\@@) { my $list = shift; push @$list, @_; } if (0 == ($child_pid = fork)) { #in child exec("my_command.exe", "my_arg1", "my_arg2"); # no more code here, since exec never returns! } else { # in parent #… parent can do other things. } print "pi_proto + 2 is ", pi_proto + 2, "\n"; print "pi_normal + 2 is ", pi_normal + 2, "\n"; mypush @list, 1, 2, 3, 4; print "\n"; print "list is (", (join ", ", @list), ")\n"; 1; • system(str) run a child process and wait for return. • wait(), waitpid(pid, FLAG) 9 Spring, 2009 Subroutine IV匿名和左值函数 13 Spring, 2009 File System Pipe lines in Perl • pipe( ) then fork( ), close one side use the other • Define and call an anonymous subroutine pipe READHANDLE, WRITEHANDLE or die "Can't open pipe."; my $subref = sub {$_[0] + $_[1]}; my $add = $subref; # make a copy of subroutine-ref print &{$add}(1,2), "\t", &$add(1,2), "\t", $add->(1,2); my $message; my $child_pid = fork(); die "Fail to fork!\n" if not defined $child_pid; • Lvalue subroutine (experimental) if ($child_pid == 0) { # in child print "I'm child. My pid is $$.\n"; close READHANDLE; $message = "Hello father. " . int rand 100 . "."; print "Child send \"$message\" to father.\n"; print WRITEHANDLE $message; close WRITEHANDLE; } else { # in parent print "I'm father, pid is $$. Child pid is $child_pid.\n" close WRITEHANDLE; $message = join "", <READHANDLE>; print "Father received : $message\n"; # waitpid $child_pid, 1; } sub Lsub : lvalue { my($index)=shift; $_[$index]; # don't say return $_[$index] here } my @a = qw(I my teaching perl.); $" = " "; print "@a\n"; Lsub(2, @a) = 'learning'; #函数返回作值,修改为'learning' print "@a\n"; # @a的值已经被修改 10 Spring, 2009 File Hanle --- Binary mode files Offset in $var, not to file • binmode(FD) • read(FD, $var, $len, $offset) # read 20 bytes from file bin.dat open(FILE, "bin.dat"); binmode(FILE); 0: Begin of file read(FILE, $buffer, 20); 1: Current position 2: End of file close(FILE); • seek(FD, $pos, $start) • tell(FD) # position of FD • sysopen(), sysread(), syswrite() • $integer = fileno(FD); …… 11 Spring, 2009 File Handle --- File Tests, Glob • Check if a file/dir/symbolic_link exists die "File missing!" if not -e "data.txt"; • Check if name is a directory: -d "name" • Check if name is a regular file: -f "name" • Lots more -x operations in perlfunc • Glob, return a list of matched file/dir names @txt_files = <*.txt>; @root_files= <c:/*.*>; # PC/MS-OS only @gif_files = glob("*.gif"); 这里的*?是文件名通配符, 不能按照perlRE规则来理解. 12 14 ...
View Full Document

Ask a homework question - tutors are online