Tên tệp OS Phần tử dữ liệu đầu tiên Phần tử dữ liệu cuối cùng Phần tử kí hiệu kết thúc tệp Con trỏ vị trí đang làm việc của tệp... Báo lỗi nếu tệp không tồn tại “w” Mở tệp mới để ghi..
Trang 1Chương 6 Xử lý bộ nhớ ngoài
ĐỖ BÁ LÂM
ViỆN CNTT&TT, TRƯỜNG ĐHBK HÀ NỘI
2
Nội dung
6.1 Khái niệm và phân loại tệp
liên quan đến nhau và có cùng kiểu dữ liệu
Biểu tượng tệp tin
Trang 26.1 Khái niệm và phân loại tệp
Tệp văn bản (text file)
• Các phần tử là các kí tự: chữ cái, chữ số, dấu câu, dấu
cách, kí tự điều khiển
• Kí tự điều khiển: kí tự về đầu dòng (mã ASCII là 10), kí
tự xuống dòng (mã ASCII là 13)
Tệp nhị phân (binary file)
• Các phần tử là các số nhị phân 0, 1 mã hóa thông tin.
• Thông tin được mã hóa: số nguyên, kí tự…
• Tệp văn bản là trường hợp riêng của tệp nhị phân
5
6.1 Khái niệm và phân loại tệp
Khác
• Mảng: lưu trữ ở bộ nhớ trong, kích thước bị hạn
chế
• Tệp: lưu trữ ở bộ nhớ ngoài, kích thước có thể lớn
hơn mảng rất nhiều
6
6.1 Khái niệm và phân loại tệp
idicator)
việc của tệp
E O F
Tên tệp OS
Phần tử dữ liệu
đầu tiên
Phần tử dữ liệu cuối cùng
Phần tử kí hiệu kết thúc tệp Con trỏ vị trí đang
làm việc của tệp
Trang 36.1 Khái niệm và phân loại tệp
8
6.2 Các thao tác với tệp
Cú pháp:
FILE *tên_con_trỏ_tệp;
6.2.2 Mở tệp
Cú pháp
tên_con_trỏ_tệp = fopen(tên_tệp, chế_độ_mở_tệp);
write (w), read write…
Trang 46.2.2 Mở tệp
Mục đích sử dụng
“r” Mở tệp đã có để đọc Báo lỗi nếu tệp không tồn tại
“w” Mở tệp mới để ghi Nếu tệp đã có thì xóa hết nội dung cũ
“a” Mở tệp để ghi dữ liệu vào cuối Nếu chưa có sẽ tạo tệp mới
“r+” Mở tệp để vừa đọc, vừa ghi Báo lỗi nếu tệp không tồn tại
“w+” Mở tệp để vừa đọc, vừa ghi Nếu tệp đã có thì xóa hết nội dung
cũ.
“a+” Mở tệp để đọc và ghi dữ liệu vào cuối Nếu chưa có sẽ tạo mới
11
6.2.2 Mở tệp
Bản chất dữ liệu của tệp
Ví dụ: FILE * f1, * f2, *f3;
Để mở tệp c:\abc.txt để đọc ta dùng lệnh
f1 = fopen("c:\\abc.txt", "rt");
Để mở tệp c:\ho_so.dat để ghi ta dùng lệnh
f2 = fopen("c:\\ho_so.dat", "wt");
Để mở tệp c:\abc.txt để vừa đọc và ghi ta dùng lệnh
f3 = fopen("c:\\abc.txt", "r+t");
Kí hiệu Bản chất dữ liệu của tệp
12
6.2.2 Mở tệp
Chú ý:
Trong C ngầm định là tệp văn bản Do vậy có thể bỏ
qua “t” trong chế độ mở tệp nếu mở tệp văn bản
Để bắt lỗi mở tệp không thành công
if((con_trỏ_tệp = fopen(tên_tệp, chế_độ_mở_tệp))
==NULL){
<Xử lí cho trường hợp mở tệp không thành công>
}else // Trường hợp mở tệp thành công
{
<Xử lí khi mở tệp thành công>
}
Trang 56.2.3 Đóng tệp
trên tệp
int fclose(FILE* <tên con trỏ tệp>);
14
6.2.4 Truy nhập tệp văn bản
Ghi dữ liệu lên tệp
Sử dụng: fprintf(), fputs(), putc()
fprintf()
int fprintf(FILE* con_trỏ_tệp, xâu_định_dạng,
[danh_sách_tham_số]);
Khác: printf in ra thiết bị ra chuẩn là màn hình (stdout),
fprintf() phải chỉ ra tên tệp ghi dữ liệu.
Thành công: số bytes ghi dữ liệu
Thất bại: EOF
Ví dụ: fprintf(fptr, “%d”, a);
6.2.4 Truy nhập tệp văn bản
int fputs(char* xâu_kí_tự, FILE* con_trỏ_tệp);
dòng
Trang 66.2.3 Truy nhập tệp văn bản
int putc(int ch, FILE* con_trỏ_tệp);
17
6.2.4 Truy nhập tệp văn bản
Đọc dữ liệu từ tệp
Sử dụng hàm: fscanf(), fgets(), fgetc(), getc();
fscanf()
int fscanf(FILE* con_trỏ_tệp, xâu_định_dạng,
[danh_sách_địa_chỉ]);
Đọc dữ liệu từ tệp: con trỏ tệp
Định dạng đọc: xâu định dạng; Lưu vào dsách địa chỉ
Thành công: số byte đọc được Thất bại: EOF
Ví dụ: fscanf(fptr, “%d %c”,&a, &c);
Trước khi sử dụng fscanf() nên dùng lệnh
fflush(con_trỏ_tệp)
18
6.2.4 Truy nhập tệp văn bản
char* fgets(char* xâu_kí_tự, int n, FILE* con_trỏ_tệp);
Đọc từ tệp một xâu kí tự và gán cho biến xâu_kí_tự
Việc đọc dừng khi đọc được đủ n-1 kí tự hoặc gặp
dấu xuống dòng
Thành công: xâu kí tự được trỏ bởi xâu_kí_tự
Thất bại: trả về con trỏ NULL
Ví dụ: fgets(hoten, 20, fptr);
Trang 76.2.4 Truy nhập tệp văn bản
int getc(FILE* con trỏ tệp);
tương ứng
20
6.2.4 Truy nhập tệp văn bản
int feof(FILE* con_trỏ_tệp);
đọc gần nhất hay chưa
E O F
E O F
Các phần tử của tệp Các phần tử của tệp
Con trỏ vị trí đang
làm việc của tệp Con trỏ vị trí đang làm việc của tệp
Chưa đọc phần tử EOF
feof() = 0
Đã đọc phần tử EOF feof() = 1
6.2.4 Truy nhập tệp văn bản
int fseek(FILE* con_trỏ_tệp, long int n, int
vị_trí_ban_đầu);
bytes
lại trả về khác 0
chuyển về đầu tệp
Trang 86.2.4 Truy nhập tệp văn bản
Vị trí bắt đầu
Ví dụ
fseek(fptr, 50, SEEK_SET);
fseek(fptr, - 40, 2);
Tên hằng Giá trị Ý nghĩa
SEEK_SET 0 Vị trị bắt đầu là tệp
SEEK_CUR 1 Vị trí bắt đầu là vị trí hiện thời
của con trỏ tệp
SEEK_END 2 Vị trí bắt đầu là cuối tệp
23
6.2.4 Truy nhập tệp văn bản
void rewind(FILE* con_trỏ_tệp);
getc(), fflush(), fprintf(), fputs(), putc(), feof(),
fseek() và rewind() ta cần khai báo tệp tiêu đề
stdio.h
6.2.4 Truy nhập tệp văn bản
Đọc
fscanf()
fgets()
getc()
Trả về EOF (trừ fgets)
tương đương nhau
Ghi
fprintf
fputs
putc
Trả về EOF
tương đương nhau
24
Trang 96.2.5 Truy nhập tệp nhị phân
int fwrite(void *địa_chỉ_biến, int số_byte, int
số_mục, FILE *con trỏ tệp);
địa_chỉ_biếnvà có kích thước số_byte*
số_mụcbytes rồi ghi lên tệp
26
6.2.5 Truy nhập tệp nhị phân
int fread(void *địa_chỉ_biến, int số_byte, int
số_mục, FILE *con_trỏ_tệp);
số_mụcbytes rồi ghi lên vùng nhớ có địa chỉ
là địa_chỉ_biến
6.2.5 Truy nhập tệp nhị phân
nhau
• fread() – fwrite()
• fscanf() – fprintf()
• fputs() – fgets()
• getc() – putc()
trừ fgets trả về NULL
Trang 10So sánh tệp văn bản và tệp nhị phân
(LF) Khi đọc sẽ kết hợp 2 ký tự thành LF
=> EOF
Lỗi cần tránh
cùng
chừng nào còn thành công
29
Nên sử dụng
một cấu trúc/mảng các phần tử cùng kiểu
30
Trang 11Ví dụ tổng hợp
hiện lần lượt các công việc (làm với cả tệp văn bản
và nhị phân) Demo dEx.c
và ghi các số thực lớn hơn 5 sang tệp
sothuc2.dat
hiển thị trong tệp sothuc2.dat Sau đó hiển thị
giá trị phần tử này ra màn hình
32
Thảo luận