Thầy Nguyễn Chánh Tín 19/2/2011 Lời tác giả: Chào các em lớp 10 chuyên Tin, đội tuyển Tin học, cùng các bạn yêu thích Tin học. Trong khuôn khổ bài viết ngắn, và để chuẩn bị kiến thức cho kỳ thi HSG vòng tỉnh sắp tới. Thầy giới thiệu với các em chuyên đề Vào ra file nhằm giúp các em chuẩn bị tốt cho việc tổ chức nhập xuất dữ liệu. Đây là một trong kỹ năng làm bài thi, nội dung này không khó nhưng nếu không khéo, các em dễ mắc phải sai lầm khi làm bà,i ảnh hưởng đến kết quả thi. Chúc các em có một kỳ thi thành công. Thầy mong chờ kết quả tốt đẹp từ các em. Niềm hy vọng của Thầy (Phan Tường, Võ Văn Tín, và các em trong đội tuyển) hãy cố lên! Chuyên đề: VÀO RA FILE – DỄ HAY LÀ KHÓ ? Nguyễn Chánh Tín – Trường THPT Chuyên Bạc Liêu Trong lập trình, đôi khi việc nhập xuất dữ liệu thật phiền hà khi bạn cần kiểm tra kết quả lập trình của bạn - công việc này thường được thực hiện bằng những bộ test. Đối với những bộ test thật dài và “cồng kềnh” thì việc nhập đi nhập lại những dữ liệu cho chương trình gây cho bạn sự khó chịu. Vì vậy những bộ test này thông thường được nhập vào từ file văn bản và kết quả xuất ra file để bạn có thể lưu trữ lâu dài. Công việc này khá đơn giản, chỉ cần bạn hiểu và nắm vững các kiến thức sau: - File là một kiểu dữ liệu gồm nhiều phần tử cùng kiểu được nhóm lại với nhau tạo thành một dãy. Thông thường có hai loại file: + File có kiểu: Mỗi phần tử của File là một dữ liệu kiểu cơ sở hay kiểu record. + File dạng text: Dữ liệu được lưu trữ trên đĩa có thành phần cơ bản là các kí tự, cấu trúc lại thành các dòng, mỗi dòng được kết thúc bởi dấu Eoln, File được kết thúc bởi dấu Eof. Ở đây chúng ta chỉ nghiên cứu đến File text và nhập xuất dữ liêu từ loại file này. 1) Khai báo biến kiểu file dạng text: * Cú pháp: Var < Tênbiến>: text; * Ví dụ: Var f, f1, f2: text; { Khai báo 3 biến file có tên f, f1, f2 là file dạng text} Khi truy xuất file ta chỉ cần thao tác đối với biến file 2) Thủ tục Assign(filevar, filename): Công dụng là để gán một tên thực sự là filename đã ghi lên đĩa cho biến file là filevar * Ví dụ: File Nhap.inp đã được ghi lên thư mục INPUT điã A: Ta đã có khai báo sau: Var f: text; Khi đó cần gán tên file trên vào biến file f ta dùng thủ tục sau: Assign(f,’A:\INPUT\Nhap.inp’); * Lưu ý: Trong tên file nếu không chỉ đường dẫn nghĩa là ta thao tác trên file ởthư mục hiện hành, thư mục hiện hành này có có thể thay đổi bằng cách vào thực đơn File/Change dir. 3) Thủ tục Reset(filevar): Công dụng để mở file đã có trên đĩa và tên đã được gán vào biến file để chuẩn bị cho việc đọc/ghi dữ liệu. * Ví dụ: Assign(f,’Nhap,inp’); RESET(f); Mở file Nhap.inp để chuẩn bị đọc ghi. 3) Thủ tục Rewrite(filevar): Tạo mới và mở file Tác dụng như thủ tục Reset nếu file chưa có trên đĩa thì tạo mới và mở file, ngược lại file đã có trên đã thì nội dung cũ sẽ bị mất đi. * Ví dụ: File Nhap.inp chưa có trên đĩa Assign(f,’Nhap.inp’); Rewrite(f); Tạo mới file Nhap.inp và mở file Nhap.inp chuẩn bị ghi. Nếu file Nhap.inp đã có trên đĩa thì nội dung trong file sẽ bị biến mất (xóa hết nội dung trong file). 4) Thủ tục CLOSE(filevar): Thủ tục này thường được sử dụng sau khi kết thúc việc thao tác trên file. Có tác dụng đóng file lại để tránh hư hao và mất mát dữ liệu. * Ví dụ: Close(f); 5) Đọc dữ liệu từ file: Việc đọc dữ liệu từ file tương tự như việc nhập dữ liệu từ bàn phím nếu như ta xem màn hình là một file. - Cú pháp: + Dạng 1: Read(filevar, biến 1, biến 2, … biến n); + Dạng 2: Readln(filevar, biến 1, biến 2, … biến n); + Dạng 3: Readln(filevar); Giữa Read và Readln có sự khác nhau là sau khi đọc xong giá trị gán vào các biến thì thủ tục Readln sẽ đưa con trỏ file xuống hàng tiếp theo còn thủ tục Read thì không. Dạng 3 có tác dụng đưa con trỏ file xuống dòng. * Ví dụ : File Nhap.inp có cấu trúc như sau 5 1 0 4 0 6 3 4 5 9 -1 9 8 4 1 0 -3 6 7 4 1 1 1 9 6 8 Với ý nghĩa là dòng đầu chứa số n là cấp của ma trận vuông, n dòng tiếp theomỗi dòng chứa n số nguyên, mỗi số cách nhau ít nhất một dấu cách. * Cách thực hiện: - Đầu tiên gán tên file Nhap.inp vào biến file f. - Mở file f để chuẩn bị đọc. - Đọc số ở dòng đầu vào biến n và xuống dòng. - Tiếp tục đọc từng dòng gán vào mảng 2 chiều. Để đọc dữ liệu này vào từ file trên ta có đoạn chương trình sau: Trong thân chương trình chính có phần khai báo: Var n: integer; a: array[1 100,1 100] of integer; {Toàn bộ thủ tục} Procedure Nhap_file; Var f : text {Khai báo biến file} i,j: integer; Begin Assign(f,’Nhap.inp’); Reset(f); Readln(f,n); {n có giá trị là 5} For i:= 1 to n do Begin for j:=1 to n do read(f, a[i,j]); Readln(f); End; Close(f); End; 6) Xuất dữ liệu ra file: Việc xuất dữ liệu từ file cũng tương tự như việc xuất dữ liệu ra màn hình nếu như ta xem màn hình là một file. - Cú pháp: + Dạng 1: Write(filevar, biến 1, biến 2, … biến n); + Dạng 2: Writeln(filevar, biến 1, biến 2, … biến n); + Dạng 3: Writeln(filevar); - Ví dụ: Write(f, a:3, b:3, c:3) Writeln(f,n); Writeln(f); Giữa Write và Writeln có sự khác nhau là sau khi ghi xong giá trị của các biến vào file thì thủ tục Writeln sẽ đưa con trỏ file xuống hàng tiếp theo còn thủ tục Write thì không. Dạng 3 có tác dụng đưa con trỏ file xuống dòng bằng cách ghi vào file kí hiệu Eoln. *Ví dụ: Ta có khai báo sau: Var a: array[1 100,1 100] of integer; m, n: integer; {cấp của mảng a) Và các biến trên có giá trị sau: m=4 n=5 a[1,1]=1; a[1, 2]=3; a[1,3]=8; a[1,4]=6; a[1,5]=2 a[2,1]=7; a[2, 2]=3; a[2,3]=9; a[2,4]=6; a[2,5]=3 a[3,1]=3; a[3, 2]=5; a[3,3]=1; a[3,4]=6; a[3,5]=4 a[4,1]=6; a[4, 2]=3; a[4,3]=10; a[4,4]=6; a[4,5]=0 Cần ghi các giá trị của biến m,n và mảng a vào file Xuat.out theo cấu trúc dòng dầu ghi hai số m,n, và m dòng tiếp theo ghi n số là nội dung của mảng a có m dòng, n cột. {Toàn bộ thủ tục} Procedure Xuat_file; var i,j: integer; f: text; Begin Assign(f, ‘Xuat.out’); Rewrite(f); {Ghi đè lên file cũ hoặc tạo mới hoàn toàn} Writeln(f, m:3, n:3); For i:=1 to m do Begin For j:=1 to n do Write(f, a[i,j]); Writeln(f); End; Close(f); End; Kết quả trong file Xuat.out sẽ có nội dung như sau: 4 5 1 3 8 6 2 7 3 9 6 3 3 5 1 6 4 6 3 10 6 0 Sau đây các bạn hãy đọc phần ví dụ sau để thấy rõ hơn việc nhập xuất dữ liệu đối với file dạng text thật đơn giản. 7) Ví dụ: Để việc minh họa nhập xuất file thêm sinh động. Ở đây chúng ta không chú trọng vào việc đưa ra bài toán hay và mang tính hàn lâm trong lập trình, mà ta chỉ chú ý vào việc nhập xuất file text như thế nào. Bài toán: Viết chương trình sắp xếp một dãy số nguyên gồm n phần tử theothứ tự tăng dần. Yêu cầu: * Dữ liệu nhập từ file text DAY.INP với cấu trúc: - Dòng đầu ghi số n là số phần tử của dãy. - Dòng thứ hai ghi n số nguyên là các phần tử của dãy mỗi số cách nhau ít nhất 1 dấu cách (khoảng trắng). * Dữ liệu xuất là một dòng chứa n số đã được sắp xếp tăng dần ghi vào file DAY.OUT. * Ví dụ: DAY.INP 10 2 3 5 9 1 0 4 7 6 8 DAY.OUT Day sau khi da sap xep la: 0 1 2 3 4 5 6 7 8 9 {Toàn văn chương trình} Const max=100; fi = ‘DAY.INP’; fo = ‘DAY.OUT’; Var a: array[1 max] of integer; n:integer; f: text; { } Procedure Nhap; Var i: integer; Begin Assign(f, fi); Reset(f); Readln(f, n); For i:=1 to n do read(f, a[i]); Close(f); End; { } Procedure Xuly; Var i,j, tam : integer; Begin For i:= 1 to n-1 do For j:= i+1 to n do If a[i]>a[j] then Begin tam:=a[i]; a[i]:=a[j]; a[j]:=tam; End; End; { } Procedure Xuat; Var i: integer; Begin Assign(f, fi); Rewrite(f); Writeln(‘Day sau khi da sap xep la: ‘): For i:=1 to n do Write(f, a[i]:3); Close(f); End; { } Begin {Thân chương trình chính} Nhap; Xuly; Xuat; End. Đến đây chắc hẳn bạn đọc có thể trả lời rằng việc nhập và xuất dữ liệu đối với file dạng text thật là dễ phải không ? . cách. * Cách thực hiện: - Đầu tiên gán tên file Nhap.inp vào biến file f. - Mở file f để chuẩn bị đọc. - Đọc số ở dòng đầu vào biến n và xuống dòng. - Tiếp tục đọc từng dòng gán vào mảng 2 chiều. Để. báo 3 biến file có tên f, f1, f2 là file dạng text} Khi truy xuất file ta chỉ cần thao tác đối với biến file 2) Thủ tục Assign(filevar, filename): Công dụng là để gán một tên thực sự là filename. hãy cố lên! Chuyên đề: VÀO RA FILE – DỄ HAY LÀ KHÓ ? Nguyễn Chánh Tín – Trường THPT Chuyên Bạc Liêu Trong lập trình, đôi khi việc nhập xuất dữ liệu thật phiền hà khi bạn cần kiểm tra kết quả