Làm việc trên các tệp trong Maple

Một phần của tài liệu lập trình trên maple (Trang 38 - 58)

2. Chu trình tính khai triển Fourier của hàm số

4.4. Làm việc trên các tệp trong Maple

4.4.1. Các thao tác cơ bản Mở một tệp Cú pháp lệnh Khai báo: fopen(name,mode); fopen(name,mode,type); Tham số:

name: tên của tập tin đ−ợc mở.

mode: Một trong các tùy chọn sau : READ, WRITE, hoặc

APPEND .

type: (tùy chọn) là TEXT hay là BINARY .

Mô tả

Hàm này dùng để mở một tệp (file) với tên tệp đã đ−ợc xác định tr−ớc, với ph−ơng thức mở cho bởi biến mode: tuỳ chọn READ cho phép mở để đọc, WRITE cho phép mở để ghi lên tệp và tuỳ chọn APPEND cho phép mở để thêm dữ liệu vào cuối tệp. Tuỳ chọn type cho biết loại tệp cần mở: type nhận giá trị là BINARY nếu tệp là tệp nhị phân (là một chuỗi liên tục các bytes) và TEXT nếu tệp thuộc loại văn bản (là một dãy các kí tự-character). Nếu lời gọi hàm không chứa tuỳ chọn thì Maple giả định tệp cần mở là tệp văn bản (tức giá trị mặc định của typeTEXT). Hàm fopen() cho lại một số nguyên là giá trị nhận diện của tệp vừa mở. Ta có thể sử dụng số nguyên này để đại diện cho tệp đó trong các thao tác trên tệp bằng cách dùng nó làm đối số cho các hàm xử lý tệp (nh− read(), save(), fclose()..). Ta có thể gán kết quả do hàm fopen() trả lại cho một biến để có thể sử dụng dần về saụ

Nếu dùng fopen() mở tệp để đọc nh−ng tệp không tồn tại trên đĩa thì fopen() sẽ thông báo lỗị Nếu dùng fopen() mở tệp để ghi mà tệp ch−a tồn tại thì fopen() tạo ra tệp mới, trong tr−ờng hợp tệp đã tồn tại thì Maple cho phép ghi đè lên dữ liệu cũ. Còn nếu mở tệp để thêm dữ liệu thì Maple cho phép thêm dữ liệu vào cuối tệp. Lệnh fopen() sẽ báo lỗi nếu tệp đang định mở đã đ−ợc mở từ tr−ớc mà ch−a đ−ợc đóng lạị

Minh hoạ

Sử dụng lệnh fopen() để mở một tệp để ghi dữ liệu:

[>fh:=fopen(`c:/test.txt`,WRITE,TEXT);

:=

[>fprintf(fh,`Day la file duoi dang van ban\n`);

30

[>fclose(fh);

Bây giờ ta có thể mở lại tệp để đọc dòng văn bản trên:

[>fh:=fopen(`c:/test.txt`,READ,TEXT);

:=

fh 0

[>readline(fh);

Day la file duoi dang van ban

Khi tệp đang mở, ta không thể mở lại tệp này nếu ch−a đóng nó lại:

[>fh1:=fopen(`c:/test.txt`,WRITE,TEXT);

Error, (in fopen) file already open

[>fclose(fh);

Ta có thể thêm dữ liệu vào tệp:

[>fh:=fopen(`c:/test.txt`,APPEND,TEXT);

:=

fh 0

[>fprintf(fh,`.Van ban duoc them vao!\n`);

24

[>fclose(fh);

Đọc lại tệp để kiểm tra tác dụng của lệnh trên:

[>fh:=fopen(`c:/test.txt`,READ,TEXT);

:=

fh 0

[>readline(fh);

Day la file duoi dang van ban

[>readline(fh);

.Van ban duoc them vao!

Đóng một tệp đã đ−ợc mở

Cú pháp lệnh:

Khai báo:

fclose(files);

Tham biến:

files : một hay một số tên hoặc số đại diện cho các tệp cần đ−ợc đóng lạị

Mô tả

Đóng tất cả các tệp đã đ−ợc mở bằng lệnh fopen(). Việc đóng các tệp này đảm bảo tất cả dữ liệu đ−ợc ghi vào tệp còn đang ở trong vùng nhớ đệm thực sự đ−ợc ghi vào đĩạ Lệnh fclose() không có giá trị trả lạị

Khi thoát khỏi Maple bằng lệnh quit, done, hoặc lệnh stop, Maple tự động

đóng tất cả các tệp đang đ−ợc mở.

Nếu tệp tồn tại trên đĩa thì lệnh fclose() với tham số là tên tệp sẽ không gây ra lỗi, nh−ng nếu tệp ch−a đ−ợc mở mà tham số cho lệnh fclose() là một biến số nguyên thì Maple sẽ báo lỗị

Minh hoạ

Mở một tệp bằng lệnh fopen() sau đó đóng lại bằng fclose():

[>fh:=fopen(`c:/test.txt`,READ,BINARY);

:=

fh 0

[>fclose(fh);

Lệnh fclose() với tham số là tên tệp sẽ không bị báo lỗi nếu tệp tồn tại trên đĩa mặc dù tệp không đ−ợc mở bằng fopen():

[>fclose(`c:/test.txt`);

Nh−ng nếu tệp không mở mà ta sử dụng lệnh fclose(sn) với tham số là một số nguyên thì Maple sẽ báo lỗi rằng tệp có chỉ số nhận dạng là sn ch−a đ−ợc mở:

[>fclose(fh);

Error, (in fclose) file descriptor not in use

Xác định vị trí cuối tệp

Cú pháp

Khai báo:

feof(file);

Tham số:

Mô tả

Hàm feof() trả lại giá trị true khi và chỉ khi gặp phải vị trí cuối cùng của tệp

trong quá trình thực hiện các lệnh readline(), readbytes(), hoặc fscanf(). Trong tr−ờng hợp ng−ợc lại, hàmfeof() trả lại giá trịfalse.

L−u ý rằng hàm feof() chỉ cho giá trị true khi thực sự gặp phải vị trí cuối tệp trong quá trình sử dụng các lệnh fscanf(), readline(),...Ví dụ dòng cuối của lệnh readline() đọc đ−ợc không chứa kí hiệu kết thúc tệp, do đó hàm feof() vẫn cho lại giá trị false. Ta phải gọi thêm một lệnh readline() nữa thì mới đạt đến vị trí cuối cùng của tệp, hàm feof() sau đó mới cho giá trị true.

Nếu khi gọi lệnh feof(filename) mà tệp có tên là filename ch−a đ−ợc mở thì Maple tự động mở tệp theo chế độ đọc READ và kiểu tệp nhị phân BINARY.

Minh họa

Mở một tập tin bằng lệnh fopen():

[>fh:=fopen(`c:/test.txt`,READ,TEXT);

:=

fh 0 Kiểm tra đã ở vị trí cuối tệp ch−a:

[>feof(fh);

false

Dùng lệnh readline() đọc nội dung của tệp fh:

[>readline(fh);

Day la file duoi dang van ban

[>readline(fh);

.Van ban duoc them vao!

Mặc dù nội dung đọc đ−ợc đã ở dòng cuối, nh−ng vị trí cuối tệp vẫn ch−a thực sự đạt đ−ợc (Maple ch−a đọc đến kí hiệu kết thúc tệp), do đó hàm feof() trả lại giá trị false:

[>feof(fh);

false

Sau khi dùng thêm một lệnh readline() nữa thì lệnh feof() mới cho giá trị đúng (true), mặc dù readline() không đọc đ−ợc nội dung gì:

[>readline(fh);

[>feof(fh);

true

[>fclose(fh);

Lấy và đặt lại vị trí hiện thời trong tệp

Cú pháp

Khai báo:

filepos(file); filepos(file,pos);

Tham biến:

file: tên tệp hay số hiệu nhận dạng (descriptor) của tệp đó.

pos: số nguyên xác định độ dịch chuyển (integer offset) trong tệp.

Mô tả

Sử dụng hàm filepos() với đối số là tên tệp (hoặc là số hiệu của tệp) sẽ cho chúng ta vị trí hiện thời trong tệp đó. Ví trí này sẽ là vị trí đ−ợc đọc/ghi trong lần đọc/ghi tiếp theọ

Sử dụng hàm filepos() với hai đối số : đối số thứ nhất là tên tệp (hay số hiệu tệp) và đối số thứ hai là một số nguyên, ta có thể đặt lại vị trí hiện tại của tệp này vào vị trí mới đ−ợc xác định bởi số nguyên đã chọ Nếu ta cho giá trị của đối số thứ hai là không xác định (infinity) thì hàm filepos() sẽ đặt vị trí hiện tại đến cuối tệp. Tr−ờng hợp tên tệp đã đ−ợc cho nh−ng tệp đó ch−a đ−ợc mở, hàm filepos() sẽ mở tệp với chế độ để đọc theo kiểu nhị phân (BINARY).

Khi xử lý một tập tin văn bản, cách duy nhất để xác định chắc chắn xem vị trí thích hợp để truyền cho hàm filepos() là gọi chính hàm filepos(). Nghĩa là chỉ những vị trí do hàm filepos() trả lại thì mới đ−ợc bảo đảm là hợp lệ để truyền cho hàm

filepos(file,value); Việc đếm những kí tự khi đọc/ghi dữ liệu là không chính xác, bởi vì những kí tự xuống dòng có thể dùng nhiều hơn một kí tự để biểu diễn.

Minh họa

Mở tệp test.txt để ghi dữ liệu:

[>f:=fopen(`c:/test.txt`,WRITE,TEXT);

:=

f 0

[>fprintf(f,`chao ban\n`);

9

[>fprintf(f,`toi la may tinh`);

[>fclose(f);

Mở tệp để đọc

[>f:=fopen(`c:/test.txt`,READ,TEXT);

:=

f 0 Ví trí tại thời điểm ban đầu là 0:

[>ht:=filepos(f);

:=

ht 0 dịch chuyển vị trí hiện tại sang vị trí tiếp theo:

[>ht:=filepos(f,ht+1);

:=

ht 1 đọc giá trị tại vị trí hiện tại 5 bytes:

[>readbytes(f,5,TEXT);

hao b

đặt vị trí hiện tại đến cuối tệp:

[>ht:=filepos(f,infinity); := ht 25 [>readbytes(f,ht); 0 [>feof(f); true [>fclose(f); Xoá một tệp Cú pháp lệnh Khai báo: fremove(files); Tham số:

Mô tả

Hàm fremove() sẽ xoá tất cả các tệp có tên nêu ra trong đối số của hàm. Nếu tệp đang đ−ợc mở thì fremove() sẽ đóng các tệp này lại sau đó sẽ xoá chúng. Nếu tệp đang đ−ợc mở thì thay vì truyền tên tệp cho đối số của hàm, ta có thể truyền số hiệu của tệp. Hàm fremove() không cho lại giá trị sau khi thực hiện.

Nếu tệp cần xoá mang thuộc tính chỉ đọc, lệnh fremove() sẽ thông báo lỗị

Minh họa

Tạo một tệp văn bản:

[>f:=fopen(`test.txt`,WRITE,TEXT);fprintf(f,`day la mot tep van ban\n`); fclose(f);

:=

f 1 23 Mở lại tệp văn bản và đọc nội dung của tệp này:

[>f:=fopen(`test.txt`,READ,TEXT);readline(f);fclose(f);

:=

f 1

day la mot tep van ban

Xóa tệp sau đó thử đọc nội dung của nó:

[>fremove(`test.txt`);

[>readline(`test.txt`);

Error, (in readline) file or directory does not exist

Đẩy dữ liệu từ vùng đệm vào đĩa

Cú pháp

Khai báo:

fflush(files);

Tham số:

files : Tên hay số hiệu của một hay nhiều tệp đang mở.

Mô tả

Hàm fflush() đ−ợc sử dụng để "đẩy" dữ liệu từ vùng nhớ đệm vào trong đĩạ Khi chúng ta sử dụng các lệnh ghi nh− fprintf(), writeline(), writebytes(),.. một phần dữ liệu đ−ợc l−u tạm thời tại vùng đệm của tệp trong bộ nhớ (vùng này do lệnh fopen() tạo ra). Khi đóng tệp thì dữ liệu này mới đ−ợc ghi hoàn toàn vào trong tệp. Vào lúc nào đó, nếu muốn toàn bộ dữ liệu đ−ợc ghi

vào đĩa mà ta vẫn ch−a muốn đóng tệp, ta có thể sử dụng hàm fflush() để đẩy toàn bộ dữ liệu từ vùng nhớ đệm vào đĩạ

Hàm fflush() không trả lại giá trị sau khi thực hiện lệnh.

Minh hoạ

Tạo một tệp văn bản và ghi vào tệp hai dòng văn bản:

[>f:=fopen(`test.txt`,WRITE,TEXT);

[>fprintf(f,`day la mot tep van ban\n`);

[>fprintf(f,`noi dung tiep theo\n`);

[>#fclose(f);

:=

f 0 23 19

Ch−a đóng tệp vội, ta thử đọc dòng văn bản từ tệp bằng lệnh readline:

[>readline(`test.txt`);

0

Rõ ràng là không đọc đ−ợc, nh−ng nếu ta dùng fflush() đẩy toàn bộ dữ liệu từ vùng nhớ vào trong đĩa, sau đó đọc bằng readline thì kết quả khả quan hơn:

[>fflush(f);

[>readline(`test.txt`);

day la mot tep van ban

đóng tệp lại: [>fclose(f); Mở một tệp để đọc/ghi mà không dùng vùng đệm Cú pháp Khai báo: open(name,mode); Tham số:

name: Tên của tệp cần đ−ợc mở.

Mô tả

Hàm open() đ−ợc dùng để mở một tệp có tên cho tr−ớc (khai báo trong đối số của hàm open()) để đọc hay ghi dữ liệu mà không sử dụng vùng nhớ đệm. Chế độ mở tệp (đọc hoặc ghi) đ−ợc xác định tuỳ thuộc vào giá trị của tham số mode là READ hoặc WRITẸ Sau khi thực hiện xong, hàm open() cho lại số hiệu của tệp (để sử dụng trong các hàm đọc/ghi khác).

Nếu tệp đ−ợc mở để đọc nh−ng ch−a tồn tại trong đĩa thì hàm open() sẽ thông báo lỗị Còn nếu tệp đ−ợc mở để ghi nh−ng tệp ch−a có trên đĩa thì open() sẽ tạo ra tệp rỗng để ng−ời dùng ghi dữ liệu vàọ Trong tr−ờng hợp tệp đang đ−ợc mở mà ta lại dùng hàm open() để mở tệp thì Maple sẽ thông báo lỗị

Minh hoạ

Mở một tệp để ghi dữ liệu bằng lệnh open():

[>restart;

[>f:=open(`test.txt`,WRITE);

:=

f 0

[>fprintf(f,`Noi dung cua tep\n`);

17

[>fprintf(f,`noi dung tiep theũ);

18

[>close(f);

Ta có thể mở lại tệp để đọc dữ liệu đ−ợc l−u trong tệp:

[>f:=open(`test.txt`,READ);

:=

f 0

[>readline(f);

Noi dung cua tep

[>readline(f);

noi dung tiep theo

[>readline(f);

0 Ta có thể xoá tệp bằng lệnh fremove():

Đóng tệp đ−ợc mở không dùng vùng nhớ đệm

Cú pháp

Khai báo:

close(file);

Tham biến:

file: tên hoặc số hiệu của một hay nhiều tệp đang mở cần đóng.

Mô tả

Hàm close() chấm dứt việc mở tệp bằng lệnh open(), đảm bảo dữ liệu đã nằm an toàn trên đĩạ Hàm close() không trả lại bất cứ giá trị gì sau khi thực hiện xong. Khi thoát Maple bằng các lệnh quit, done hoặc lệnh stop thì các tệp đang mở sẽ đ−ợc Maple tự động đóng lại tr−ớc khi kết thúc ch−ơng trình.

Nếu chúng ta muốn thay đổi chế độ mở tệp (từ chế độ mở để đọc sang chế độ mở để ghi dữ liệu hoặc ng−ợc lại), chúng ta phải đóng tệp lại, sau đó mới mở ra theo chế độ mớị

Việc dùng hàm close() để đóng một tệp đã tồn tại trên đĩa nh−ng ch−a đ−ợc mở sẽ không hề gây ra lỗị Ta có thể lợi dụng khả năng này để đảm bảo chắc chắn một tệp ta định mở đã hoàn toàn đ−ợc đóng. Chẳng hạn chúng ta cần mở tệp test.txt để đọc dữ liệu từ tệp đó nh−ng không biết chắc là tệp này đã mở ch−a, ta có thể dùng lệnh close(`test.txt`); để đóng nó lại (nếu tệp này đang mở thì Maple sẽ

đóng lại, còn nếu nó ch−a đ−ợc mở thì Maple cũng không thông báo lỗi gì), sau đó mới dùng lệnh open() để mở tệp. Minh hoạ Mở một tệp để ghi: [>f:=open(`closẹtxt`,WRITE); := f 0

[>writeline(f,`dong thu nhat`,`dong thu haỡ);

27 Dùng lệnh close() đóng tệp lại:

[>close(f);

Việc đóng một tệp đã tồn tại trên đĩa mà ch−a đ−ợc mở không hề gây ra lỗi:

[>close(`closẹtxt`);

Để đảm bảo chắc chắn tệp closẹtxt đã hoàn toàn đóng tr−ớc khi mở lại, ta gọi

close() tr−ớc, sau đó mới dùng lệnh open():

[>close(`closẹtxt`);

[>readline(f);

[>close(f);

:=

f 0

dong thu nhat

Lệnh ghi dữ liệu

Cú pháp

Khai báo:

save filename;

save name01, name02,...name0n, filename;

Tham số:

filename: Tên tệp cần l−u dữ liệụ

name01, name02,... name0n: tên của n biến cần l−u giá trị.

Mô tả

Hàm save dùng để l−u các tên (bao gồm tên biến, tên biểu thức,...) trong một phiên tính toán của Maple vào trong một tệp.

Dạng phát biểu thứ nhất trong phần khai báo, câu lệnh savefilename sẽ ghi tất

các tên hiện có trong phiên làm việc của Maple (Maple session) vào trong tệp có tên đ−ợc xác định bởi filename.

Trong dạng phát biểu thứ hai, các biến xác định name01, name02, ...name0n sẽ đ−ợc viết vào trong tệp có tên là filename nh− là một chuỗi các câu lệnh gán. Nếu một tên name0i không đ−ợc gán một giá trị thì phép gán name0i:=name0i đ−ợc viết vào tệp.

Nếu filename có chứa những kí tự không bình th−ờng ( ví dụ:"/",".",...) thì tên phải đ−ợc đóng trong dấu ngoặc.

Nếu filename kết thúc bằng kí tự ".m" thì các biến cùng với các giá trị đ−ợc gán cho chúng đ−ợc ghi vào tệp theo dạng thức nội tại của Maplẹ Nếu không thì chúng đ−ợc ghi theo dạng thức ngôn ngữ của Maple thông th−ờng.

Minh hoạ

Tạo một số dòng lệnh và ghi vào một tệp bằng lệnh save.

[>read `savẹm`;

[>a;

[>n; 3628800 Lệnh đọc dữ liệu read Cú pháp Khai báo: read filename; Tham biến:

filename: Tên tệp cần đọc dữ liệụ

Mô tả

Chúng ta dùng lệnh read để đọc các tệp có dạng thức nội bộ và dạng thức ngôn ngữ của Maple vào trong máỵ Nếu tên tệp có kết thúc bằng kí tự ".m" hoặc ".mws" thì tệp đ−ợc đọc vào theo dạng nội bộ của Maple, khi đó các đối t−ợng ghi trong tệp đ−ợc đ−ợc đọc vào trong bộ nhớ và sẵn sàng đ−ợc sử dụng. Nếu tên tệp chứa các kí tự lạ nh− ".", "/",.. thì tên tệp đấy phải đ−ợc đặt trong cặp dấu ngoặc.

Nếu tệp có dạng thức ngôn ngữ (language format), các câu lệnh trong tệp đ−ợc đọc và thực thi giống nh− là khi chúng đ−ợc gõ vàọ Tuy nhiên , các câu lệnh không đ−ợc hiện trên màn hình trừ tr−ờng hợp lệnh interface(echo) đ−ợc đặt bằng 2 hay cao hơn.

Dạng thức của các tệp do lệnh save quy định.

Minh hoạ

Khởi động lại phiên làm việc.

[>restart;

Ghi các lệnh sau vào tệp theo định dạng ngôn ngữ của Maple:

[>u:=proc(n) local a,b,c,i; a:=1;b:=1; if n<0 then print(`Khong co gia trỡ); elif n<=1 then a; else for i from 2 to n do c:=a+b;a:=b;b:=c; od; c;

fi; end:

[>a:=u(1000):

[>save `test`;

Sau đó ta có thể đọc tệp này vào bằng lệnh read:

[>read `test`; u := proc ( )n locala b c i, , , ; := a 1; := b 1; <

n 0 print(`Khong co gia trỡ) if then

n 1 a

elif then

; for fromi 2tondo c := a b + ;a := b;b := cend do c

else end if end proc [>fremove(`test`); 4.4.2. Đọc dữ liệu từ tệp vào Đọc một dòng từ tệp Cú pháp Khai báo: readline(filename); readline(); Tham biến:

filename: Tên của một tập tin hay là kí hiệu nhận dạng (descriptor).

Mô tả

Ta sử dụng hàm readline() để đọc dòng dữ liệu tiếp theo từ tệp đã chỉ rõ. Hàm

readline cho lại kết quả là một xâu kí tự(string) chứa cả dòng dữ liệu đọc đ−ợc từ tệp. Kí tự xuống dòng đọc đ−ợc từ tệp sẽ bị xoá tr−ớc khi dòng dữ liệu gán cho xâu kí tự đó.

Nếu không còn dòng dữ liệu nào để đọc nữa, hàm readline cho kết quả là số 0 (thay vì một xâu kí tự) để báo rằng đã đến cuối tệp. Nếu nh− tệp đ−ợc chỉ rõ bằng tên của nó (tức là đối số truyền cho hàm readline là tên tệp) thì Maple tự động đóng tệp đó lạị

lệnh này sẽ trực tiếp đọc một dòng lệnh đ−ợc gõ vào tại vị trí dấu đợi lệnh tiếp theo của Maple và Maple sẽ không thực hiện dòng lệnh này nữạ Khi có tệp đang đ−ợc mở, lệnh readline() sẽ đọc dòng tiếp theo của tệp.

Một phần của tài liệu lập trình trên maple (Trang 38 - 58)

Tải bản đầy đủ (PDF)

(58 trang)