Các lệnh vào/ra dữ liệu: 2Nhập dữ liệu:

Một phần của tài liệu Phân tích Cấu trúc chương trình Perl, các kiểu dữ liệu và các thao tác trên dữ liệu (Trang 41)

Nhập vào từ STDIN

Việc đọc từ lối vào chuẩn (thông qua tước tiệu tệp STDIN-viết tắt của Standard Input trong Perl) thì thật dễ dàng. Chúng ta đã làm việc này với toán tử <STDIN>. Việc dùng toán tử này trong ngữ cảnh vô hướng trả về cho bạn bạn một dòng của cái đang được nhập vào, hoặc undef nếu không còn dòng nào nữa, giống như:

$a = <STDIN>; # đọc dòng tiếp theo

Việc dùng toán tử này trong ngữ cảnh mảng sẽ cho bạn tất cả các dòng còn lại như một danh sách - mỗi phần tử của danh sách này là một dòng, bao gồm cả ký tự xuống dòng mới của nó. Chúng ta đã thấy điều này trước đây, nhưng xem như đây là bài ôn tập, nó có thể trông như một cái gì đó tựa như thế này:

Một cách điển hình, một trong những điều bạn muốn làm là đọc tất cả các dòng một lúc, và làm điều gì đó trên mỗi dòng. Một cách chung để làm điều này là:

while ($_ = <STDIN>) {

# xử lí $_ tại đây (cho từng dòng) }

Cứ mỗi khi một dòng được đọc vào, <STDIN> lại trả về một giá trị đúng (true), cho nên chu trình tiếp tục thực hiện. Khi <STDIN> không còn dòng nào để đọc nữa thì nó trả về undef, tương đương với giá trị sai (false), kết thúc chu trình.

Việc đọc một giá trị vô hướng từ <STDIN> vào $_ và dùng giá trị đó làm biểu thức điều khiển cho chu trình (như trong ví dụ vừa rồi) thường hay xuất hiện đến mức Perl có hẳn một cách viết tắt cho nó. Bất kì khi nào việc kiểm tra chu trình chỉ bao gồm một toán tử đưa vào (cái gì đó tựa như <...>), thì Perl tự động sao dòng được đọc vào sẽ lưu trong biến $_.

while ($_ = <STDIN>) { # giống while ($_ = <STDIN>) chop; # giống chop($_)

# các phép toán khác với $_ ở đây }

Vì biến $_ là mặc định cho nhiều phép toán nên bạn có thể tiết kiệm khá nhiều cú gõ phím theo cách này.

<STDIN> xem như một vô hướng

Tại điểm này, bạn có thể tự hỏi làm sao lấy được một giá trị vào trong chương trình Perl. Sau đây là cách đơn giản nhất. Mỗi lần bạn dùng <STDIN> ở chỗ đang trông đợi một giá trị vô hướng, thì Perl sẽ đọc toàn bộ dòng văn bản tiếp từ lối vào chuẩn (cho tới dấu dòng mới đầu tiên), và dùng xâu đó như giá trị cho <STDIN>. Đầu vào chuẩn có thể mang nhiều nghĩa, nhưng chừng nào bạn còn chưa làm điều gì đó thì nó vẫn còn mang nghĩa là thiết bị cuối của người dùng, người đã gọi chương trình của bạn (có thể là bạn). Nếu không có gì chờ đợi để đọc cả (trường hợp điển hình, chừng nào bạn còn chưa gõ xong toàn bộ dòng), thì chương trình Perl sẽ dừng và đợi cho bạn đưa vào một số kí tự theo sau bằng một dấu dòng mới (xuống dòng).

Giá trị xâu của <STDIN> về điển hình có một dấu dòng mới ở cuối của nó. Thông thường nhất là bạn muốn gỡ bỏ cái dấu dòng mới đó đi (có sự khác biệt lớn giữa hello và hello\n) (dùng toán tử chop() để hỗ trợ). Một dãy data input đại loại như thế này:

<STDIN> như một mảng

Một toán tử ta đã thấy trước đây cũng cho giá trị khác tong hoàn cảnh mảng là <STDIN>. Như đã mô tả trước đây, <STDIN> cho dòng tiếp của cái vào trong hoàn cảnh vô hướng. Bây giờ, trong hoàn cảnh mảng, toán tử này cho lại tất cả phần dòng còn lại cho tới cuối tệp. Mỗi dòng đều được cho lại như một phần tử tách bạch của danh sách. Chẳng hạn:

@a = <STDIN>; # tương tự như while ($a = <STDIN>) {@a = (@a, $a);}

Nếu một người chạy chương trình này gõ vào ba dòng, rồi nhấn Control-D (để chỉ ra "cuối tệp"), thì mảng kết thúc với ba phần tử. Mỗi phần tử sẽ là một xâu mà kết thúc bằng một dấu xuống dòng, tương ứng với ba dòng có kết thúc là dấu dòng mới đã gõ vào

Nhập vào từ toán tử "hình thoi"

Một cách khác để đọc dữ liệu vào là dùng toán tử hình thoi: <>. Toán tử này giống như <STDIN> ở chỗ nó trả về một dòng riêng trong ngữ cảnh vô hướng (undef nếu tất cả các dòng này đã được đọc), hay tất cả các dòng còn lại nếu được dùng trong ngữ cảnh mảng. Tuy nhiên, khác với <STDIN>, toán tử hình thoi lấy dữ liệu từ tệp hay các tệp được xác định trên dòng lệnh được gọi trong chương trình Perl. Chẳng hạn, nếu bạn có một chương trình mang tên kitty, bao gồm:

#!/usr/bin/perl while (<>) { print $_; }

và nếu bạn gọi kitty với: kitty file1 file2 file3 thì toán tử hình thoi sẽ đọc từng dòng của file1 tiếp theo là từng dòng của file2 và file3 lần lượt, và cuối cùng trả về undef khi tất cả các dòng đã được đọc hết.

Như bạn có thể thấy, kitty làm việc giống như cat (một lệnh của Linux), gửi tất cả các dòng của tệp có tên ra thiết bị xuất chuẩn (STDOUT) theo tuần tự. Nếu, giống cat, bạn

không xác định bất kì tên tệp nào trên dòng lệnh thì toán tử hình thoi sẽ tự động đọc từ STDIN.

Về mặt kĩ thuật, toán tử hình thoi không nhìn y nguyên vào các tham số của dòng lệnh - nó làm việc từ mảng @ARGV. Mảng này là một mảng đặc biệt được bộ thông dịch Perl đặt sẵn là một danh sách các tham số của dòng lệnh. Mỗi tham số dòng lệnh được bỏ đi sau khi Perl đã lấy các chuyển mạch dòng lệnh của nó để đưa vào một phần tử tách biệt của mảng @ARGV. Bạn có thể xử lý danh sách này theo bất kì cách nào bạn muốn. Bạn thậm chí có thể đặt mảng này bên trong chương trình của mình, và khi đó toán tử hình thoi làm việc trên danh sách mới thay vì các tham số của dòng lệnh, như thế này:

#!/usr/bin/perl

@ARGV = ("aaa", "bbb", "ccc");

while (<>) { # xu ly cac file aa, bbb va ccc print "This line is: $_";

}

2.3 Xuất dữ liệu:Đưa ra STDOUT Đưa ra STDOUT (adsbygoogle = window.adsbygoogle || []).push({});

Perl dùng các toán tử print và printf để ghi/xuất dữ liệu ra STDOUT. Ta hãy xem cách chúng được dùng.

2.3.1 Dùng print cho cách xuất thông thường

Chúng ta đã dùng print để hiển thị văn bản ra STDOUT (thường được hiển là màn hình). Ta hãy mở rộng thêm một chút.

Toán tử print nhận một danh sách các xâu, và gửi lần lượt từng xâu ra STDOUT. Điều có thể không hiển nhiên là ở chỗ print thực sự chỉ là toán tử danh sách, và trả về một giá trị giống như bất kì toán tử danh sách nào khác. Nói cách khác:

$a = print ("xin chao", "moi nguoi", "\n");

sẽ là một cách khác để nói "xin chao moi nguoi". Giá trị trả lại của print là một giá trị đúng hay sai, chỉ ra sự thành công của việc in. Nó gần như bao giờ cũng thành công, trừ

phi bạn gặp lỗi vào/ra nào đó, cho nên $a trong trường hợp này sẽ gần như bao giờ cũng là 1.

Đôi khi, bạn sẽ cần bổ sung thêm các dấu ngoặc vào print như được nêu trong ví dụ này, đặc biệt nếu cái đầu tiên mà bạn muốn in bắt đầu với một dấu mở ngoặc tròn, như trong:

print (2+3), "xin chao"; # sai! in 5, bỏ qua "xin chao" print ((2+3), "xin chao"); # đúng! in "5xin chao" print 2+3, "xin chao"; # cũng đúng! in "5xin chao"

2.3.2 Dùng printf xuất dữ liệu theo định dạng

Bạn có thể muốn có một chút ít kiểm soát với dữ liệu in ra hơn là khả năng print cung cấp. Trong thực tế, bạn có thể quen với cách xuất dữ liệu có định dạng của hàm printf trong C. Perl cung cấp một phép toán tương ứng với cùng tên.

Toán tử printf nhận một danh sách tham số (được bao trong dấu ngoặc tròn tuỳ chọn, tương tự như đối với toán tử print). Tham số thứ nhất là một xâu kiểm soát định dạng, xác định cách in các đối còn lại. Nếu bạn còn chưa quen thuộc với hàm printf chuẩn, thì bạn xem hướng dẫn trong man printf, và nếu có thể bạn nên xem ở chương 3 của quyển sách Programming Perl. Tuy nhiên, hãy xem một ví dụ:

printf "%15s %5d %10.2f\n", $s, $n, $r;

toán tử printf trong ví dụ ở trên sẽ in ra xâu $s trong một trường 15 kí tự, rồi đến dấu cách, rồi đến $n xem như một số nguyên trong trường 5 kí tự, rồi lại đến một dấu cách khác, tiếp theo đến lượt $r được tin như giá trị dấu phẩy động với 2 vị trí thập phân trong một trường 10 kí tự, và cuối cùng là một dấu xuống dòng mới

Một số ví dụ vào/ra cơ bản

vd1:

#!/usr/bin/perl

$name = <STDIN>; chop($name);

print "Xin chao ban $name!\n";

vd2:

#!/usr/bin/perl

print "Ten ban la gi? "; $name = <STDIN>; chop($name);

if ($name eq "Jenny") { #chao Jenny

print "Chao Jenny! Lam bai tap di chu!\n"; } else {

#chao binh thuong

print "Xin chao ban $name!\n";

}

Một phần của tài liệu Phân tích Cấu trúc chương trình Perl, các kiểu dữ liệu và các thao tác trên dữ liệu (Trang 41)