Bài giảng Kỹ thuật lập trình - Chương 7: Tệp, cung cấp cho người học những kiến thức như: Khái niệm tệp; Tệp văn bản; Tệp nhị phân. Mời các bạn cùng tham khảo!
Trang 1CHƯƠNG 7: TỆP
BÀI GIẢNG HỌC PHẦN
KỸ THUẬT LẬP TRÌNH
Trang 2Nội dung
7.1 Khái niệm tệp
7.2 Tệp văn bản
7.3 Tệp nhị phân
Trang 37.1 Khái niệm tệp
• Tệp: là một tập hợp các dữ liệu cùng kiểu, có liênquan với nhau, được nhóm lại với nhau thành mộtdãy và thường được lưu trữ trên các thiết bị nhớngoài dưới một tên gọi nào đó Tệp tồn tại ngay cảkhi chương trình đã kết thúc hoặc tắt máy, thườngđược lưu trữ để sử dụng lâu dài
• Khi khai báo biến tệp không cần xác định số phần
tử của tệp
• Khi lưu trữ, các phần tử của tệp được sắp xếp thànhmột dãy các byte liên tiếp nhau, sau phần tử dữ liệu
Trang 47.2 Tệp văn bản
• Khai báo tệp văn bản
• Mở tệp văn bản
• Đóng tệp văn bản
• Đọc/ghi một ký tự với tệp văn bản
• Đọc/ghi theo kiểu văn bản
• Đọc/ghi một xâu ký tự
Trang 5Khai báo tệp văn bản
• Tệp văn bản:
- Lưu trữ dữ liệu dưới dạng ký tự
- Có 2 cách truy xuất theo kiểu ký tự:
+ Truy xuất theo từng ký tự
+ Truy xuất theo từng dòng
• Cú pháp khai báo biến tệp:
FILE *con_trỏ_tệp;
Ví dụ: FILE *fp;
Trang 6Mở tệp văn bản (1)
• Cú pháp:
con_trỏ_tệp = fopen("tên_tệp", "kiểu_truy_nhập");
- Hàm fopen nếu mở tệp thành công sẽ trả về con trỏtệp cho tệp được mở, nếu tệp cần mở không tồn tạitrên ổ đĩa thì hàm fopen trả về giá trị NULL
- "tên_tệp" có thể bao gồm cả đường dẫn đầy đủ tớitệp
Ví dụ: "C:\SV\tepvanban.txt"
Trang 7Mở tệp văn bản (2)
• Cú pháp: (tiếp)
- "kiểu_truy_nhập" có thể nhận các giá trị sau:
"r" mở tệp để đọc, nếu tệp chưa tồn tại thì báo lỗi
"w" mở tệp mới để ghi, nếu tệp đã tồn tại sẽ bị xóa
"a" mở tệp để ghi bổ sung vào cuối tệp, nếu tệpchưa tồn tại thì tạo tệp mới
"r+" mở tệp để cập nhật (đọc/ghi), nếu tệp chưa tồntại thì báo lỗi
"w+" mở tệp mới để đọc/ghi, nếu tệp đã tồn tại sẽ bịxóa
"a+" mở tệp để đọc/ghi bổ sung vào cuối tệp, nếu
Trang 8+ Xóa vùng đệm (khi đang đọc)
+ Giải phóng biến con trỏ để nó có thể dùng cho tệpkhác Nếu thành công hàm cho giá trị 0, trái lại hàmcho EOF
• Ví dụ:
fclose(fp);
Trang 9Đọc/ghi một ký tự với tệp văn bản (1)
Trang 10Đọc/ghi một ký tự với tệp văn bản (2)
Nếu thành công hàm cho mã ký tự đọc được (
[0,255], nếu gặp cuối tệp hoặc có lỗi thì hàm choEOF
Hàm đọc một lượt cả 2 mã 13 và 10 rồi trả về giá trị10
Khi gặp mã 26 thì hàm trả về EOF
Trang 11Đọc/ghi theo kiểu văn bản (1)
• Ghi dữ liệu theo định dạng:
fprintf(fp,xâu_định_dạng, danh_sách_tham_số);trong đó: fp là con trỏ tệp
Giá trị các tham số được ghi lên tệp theo định dạngtrong xâu_định_dạng
Nếu thành công hàm trả về giá trị nguyên bằng sốbyte dữ liệu được ghi lên tệp, khi có lỗi thì hàm choEOF
Trang 12Đọc/ghi theo kiểu văn bản (2)
• Đọc dữ liệu theo định dạng:
fscanf(fp,xâu_định_dạng, danh_sách_tham_số);trong đó: fp là con trỏ tệp
Đọc dữ liệu từ tệp, biến đổi theo định dạng và lưukết quả vào các tham số
Hàm trả về giá trị bằng số trường được đọc
Trang 13Ghi xâu s lên tệp fp (không ghi ký tự '\0' vào tệp)
Nếu thành công hàm trả về ký tự cuối cùng đượcghi vào tệp, khi có lỗi thì hàm cho EOF
Trang 15Đọc/ghi một xâu ký tự (3)
• Đọc một xâu ký tự từ tệp: (tiếp)
Quá trình đọc kết thúc khi:
+ Hoặc đã đọc n-1 ký tự
+ Hoặc gặp dấu xuống dòng (cặp mã 13 10), khi đó
mã 10 được đưa vào xâu kết quả
+ Hoặc kết thúc tệp
Xâu kết quả được bổ sung thêm ký tự '\0'
Khi đọc thành công, hàm trả về địa chỉ vùng nhậnkết quả, nếu có lỗi hoặc đọc hết tệp thì hàm trả về
Trang 17printf("Nhap dong thu %d
(nhan Enter de ket thuc):",i);fflush(stdin);
gets(s);
if (s[0]=='\0') break;
if (i>1) fputc(10,fp);
fputs(s,fp);
Trang 18return 0;
}
Trang 19• Đọc/ghi một mẫu tin
• Truy cập ngẫu nhiên
Trang 20Khai báo tệp nhị phân
• Tệp nhị phân:
- Dùng để lưu trữ dữ liệu theo dạng “nhị phân”
• Cú pháp khai báo biến tệp: tương tự như tệp vănbản
FILE *con_trỏ_tệp;
Ví dụ: FILE *fp;
Trang 21Mở tệp nhị phân
• Cú pháp: tương tự như tệp văn bản
con_trỏ_tệp = fopen("tên_tệp", "kiểu_truy_nhập");Tuy nhiên "kiểu_truy_nhập" có thể nhận các giá trị:
"rb" mở tệp để đọc, nếu tệp chưa tồn tại thì báo lỗi
"wb" mở tệp mới để ghi, nếu tệp đã tồn tại sẽ bị xóa
"ab" mở tệp để ghi bổ sung vào cuối tệp, nếu tệpchưa tồn tại thì tạo tệp mới
"r+b" mở tệp để cập nhật (đọc/ghi), nếu tệp chưatồn tại thì báo lỗi
"w+b" mở tệp mới để đọc/ghi, nếu tệp đã tồn tại sẽ
bị xóa
Trang 23Đọc/ghi một ký tự với tệp nhị phân
Tương tự như tệp văn bản
Trang 24Ghi giá trị n vào tệp fp dưới dạng 2 byte
Khi ghi thành công, hàm trả về giá trị n, khi có lỗihàm trả về EOF
Trang 26Đọc/ghi một mẫu tin (1)
• Thường áp dụng với dữ liệu kiểu thực, kiểu cấu trúc
• Ghi một mẫu tin vào tệp:
fwrite(p,a,n,fp);
trong đó:
- p là con trỏ kiểu void trỏ tới vùng nhớ chứa dữliệu cần ghi
- a là kích thước của mẫu tin (tính bằng byte)
- n là số mẫu tin cần ghi
Trang 27Đọc/ghi một mẫu tin (2)
Trang 28Truy cập ngẫu nhiên (1)
• Con trỏ tệp: Mỗi tệp có một con trỏ xác định vị tríđọc/ghi trên tệp (con trỏ chỉ vị - file positionlocator) Khi mở tệp để đọc/ghi, con trỏ luôn trỏ vàođầu tệp (trừ trường hợp tệp được mở theo chế độđọc/ghi bổ sung thì con trỏ ở cuối tệp)
• Đọc/ghi dữ liệu tuần tự: (theo hướng từ đầu đếncuối tệp) đọc/ghi tại vị trí hiện tại của con trỏ, saukhi hoàn thành, con trỏ dịch chuyển một số bytebằng số byte đã đọc/ghi
Hạn chế
Trang 29Truy cập ngẫu nhiên (2)
• Truy cập ngẫu nhiên: (tiếp)
- Hàm chuyển con trỏ chỉ vị về đầu tệp:
rewind(fp);
trong đó fp là con trỏ tệp
Trang 30Truy cập ngẫu nhiên (3)
+ n (kiểu int) là vị trí xuất phát, có thể nhận giá trị:
n = SEEK_SET hoặc 0: Xuất phát từ đầu tệp
n = SEEK_CUR hoặc 1: Xuất phát từ vị trí con
trỏ hiện tại
n = SEEK_END hoặc 2: Xuất phát từ cuối tệp
Hàm trả về giá trị 0 khi di chuyển thành công, khác
0 trong trường hợp có lỗi
Trang 31Truy cập ngẫu nhiên (4)
• Hàm trả về vị trí hiện tại của con trỏ:
Trang 32Truy cập ngẫu nhiên (5)
Trang 34printf("Ma can bo: ");gets(cb.macb);
printf("Ho ten: ");gets(cb.hoten);
printf("Ma pb: ");gets(cb.mapb);
fwrite(&cb,sizeof(canbo),1,fp);
}
fclose(fp);
Trang 35Ví dụ (3)
printf("Danh sach can bo vua nhap la:\n");
fp = fopen("canbo.dat","rb");
while (fread(&cb,sizeof(canbo),1,fp)>0)printf("%-6s %-30s %-6s\n",
cb.macb,cb.hoten,cb.mapb);
fclose(fp);
return 0;
}
Trang 36• Làm sạch vùng đệm của tất cả các tệp đang mở:
fflushall(void);
Nếu thành công hàm trả về số tệp đang mở, ngượclại cho EOF
Trang 37Một số hàm xử lý tệp (2)
• Kiểm tra lỗi:
ferror(fp);//kiểm tra lỗi thao tác trên tệp fp
Hàm cho giá trị 0 nếu không có lỗi, ngược lại chogiá trị khác 0
• Thông báo lỗi hệ thống:
perror(s); //s là con trỏ trỏ tới 1 xâu ký tự
Hàm in xâu s và thông báo lỗi
• Kiểm tra cuối tệp:
feof(fp); //fp là con trỏ tệp
Hàm cho giá trị bằng 0 khi đọc đến cuối tệp, khác 0
Trang 38Một số hàm xử lý tệp (3)
• Xóa tệp:
unlink(s); //s là tên tệp cần xóa
Hàm cho giá trị 0 khi xóa thành công, ngược lại choEOF
Cũng có thể sử dụng hàm sau để xóa tệp:
remove(s); //s là tên tệp cần xóa
• Ví dụ về kiểm tra lỗi khi mở tệp: