Lập trình C Chương 6. Thao tác trên tập tin (3 tiết)
Trần Minh Thái Email: minhthai@huflit.edu.vn Website: www.minhthai.edu.vn Cập nhật: 20/03/2017
Nội dung
• Khái niệm
• Khai báo
• Các thao tác trên tập tin
• Bài tập
2
KHÁI NIỆM
Khái niệm
ữ ữ ệ ở ộ
ớ
ư • File cho phép l u tr d li u
b nh ngoài (đĩa)
ữ ệ
ể ư
ướ
ớ
• File có th l u d li u kích th
ớ ố c l n v i s
ượ
ầ ử
ỉ
ế ế ch b h n ch ị ạ
l
ng các ph n t
ạ không h n ch (
ượ
ủ ộ
ớ
ở b i dung l
ng c a b nh ngoài
)
4
Khái niệm
• Biến File: là một biến thuộc kiểu dữ liệu tập tin dùng để đại
diện cho một tập tin
• Con trỏ tập tin: Xác định vị trí trong tập tin khi thao tác đọc /ghi
• Phân loại File:
• File text
• File nhị phân
5
File text
• Dùng để ghi các ký tự lên đĩa dưới dạng mã Ascii
• Dữ liệu của tập tin được lưu trữ thành các dòng, mỗi dòng được
kết thúc bằng ký tự xuống dòng (new line), ký hiệu ‘\n’
• Mỗi tập tin được kết thúc bởi ký tự EOF (End Of File) có mã Ascii
là 26 (xác định bởi tổ hợp phím Ctrl + Z)
6
File nhị phân
• Một dãy các bytes liên tục
• Nội dung dữ liệu được mã hóa
7
CÁC THAO TÁC TRÊN FILE
Các thao tác khi thao tác trên File
1.
Khai báo con trỏ file
2. Mở file
3.
Thao tác đọc/ ghi trên file
4.
Đóng file
9
Khai báo con trỏ file
• Cú pháp:
FILE
• Các biến trong danh sách phải là các con trỏ và được phân cách
bởi dấu phẩy(,)
• Ví dụ: FILE *f1, *f2;
10
Mở file
• Cú pháp:
FILE *fopen(char *path, const char *mode)
• Trong đó:
• path: chuỗi chỉ đường dẫn đến tập tin trên đĩa
• mode: chuỗi xác định cách thức mà tập tin sẽ mở
• Hàm fopen trả về một con trỏ tập tin. Nếu có lỗi xuất hiện trong
khi mở tập tin thì trả về con trỏ NULL
11
Các thông tin Mode
Mode
ả
ậ
ớ ể
ị
ị
ả ể ọ ể
ị
ể ọ
ả
ể ọ
ậ
ả ớ ậ
ể ọ ể ọ
ị ị
12
Ý nghĩa ả ể ọ ở ậ r M t p tin văn b n đ đ c ạ T o ra t p tin văn b n m i đ ghi w ậ ố a N i vào t p tin văn b n ở ậ rb M t p tin nh phân đ đ c ậ ạ wb T o ra t p tin nh phân đ ghi ố ậ ab N i vào t p tin nh phân ở ộ ậ r+ M m t t p tin văn b n đ đ c/ghi ạ w+ T o ra t p tin văn b n đ đ c ghi ể ả ạ ố a+ N i vào hay t o m i t p tin văn b n đ ọ đ c/ghi ậ ở ạ ậ ố
ớ ậ
ị
r+b M ra t p tin nh phân đ đ c/ghi w+b T o ra t p tin nh phân đ đ c/ghi ạ a+b N i vào hay t o m i t p tin nh phân
Ví dụ tạo mới file text “test.txt” ở ổ đĩa D:
FILE *f;
f = fopen(“D:\\test.txt”, “w”);
if (f!=NULL)
{
/* Các câu lệnh để thao tác với tập tin*/
/* Đóng tập tin*/
}
13
Đóng tập tin
• Cú pháp:
int fclose(FILE *f)
• Trong đó f là con trỏ tập tin được mở bởi hàm fopen()
• Trả về 0: đóng tập tin thành công
• Trả về EOF nếu có xuất hiện lỗi
• Đóng tất cả các tập tin lại: int fcloseall()
14
Thao tác trên File text
́ ̣ ̣ STT TÊN HA M̀ ̃ Ử Y NGHI A S DUNG VI DÚ
̣ ̣ ĐOC TÂP TIN
̣ ̣ ọ ư ̣ ừ ̣ ̃ Đ c d liêu t tâp tin 1 fscanf(FILE *, đinh dang, ca c ́ tham biê n)́ fscanf(f, “%d”, &x);
̣ ̣
́ ươ ́ ơ ́ ́ c tô i 2 ̣ ̣ ỗ fgets(chu i, ki ch th đa, FILE *) char s[80]; fgets(s, 80, f);
̀ ự ̀ ́ ̃ ự ư tâp t Đoc chuô i ky t ́ ́ ́ ươ tin v i ki ch th c tô i ́ đa cho phe p, hoăc găp ́ ́ ky t xuô ng do ng
́ ̀ ̣ ̣ 3 getc(FILE *) Đoc ky t ự ư t tâp tin char c=getc(f);
̣ GHI TÂP TIN
̣ ̣
́ ̀ ữ ̣ ̣ Ghi d liêu va o tâp tin fprintf(f, “%d”, x); 1
fprintf(FILE *, đinh dang, ́ ca c tham biê n)
̃ ́ ̀ự ̣ va o tâp 2 ̃ fputs(chuô i, FILE *) Ghi chuô i ky t tin fputs(“Vi du”, f); 15
Ví dụ
Tạo tập tin văn bản “so.out” gồm n số nguyên, các số của dãy
được tạo ngẫu nhiên có giá trị không vượt quá M (n, M đọc từ tập
tin “so.inp”). Kết quả chương trình là 1 tập tin văn bản có dòng thứ
nhất ghi số n; n dòng tiếp theo ghi các số tạo được, mỗi số trên
một dòng
File so.out
3
File so.inp
5
3
7
10
2
16
# define in “SO.INP”
int main() # define out “SO.OUT”
{
void DocFile(int &n, int &M) int n, M;
{
srand((unsigned int)time(NULL)); FILE *fi;
DocFile(n, M);
fi = fopen(in, "r"); GhiFile(n, M);
fscanf(fi, "%d%d", &n, &M); return 0;
fclose(fi); }
} void GhiFile(int n, int M) {
FILE *fo;
fo = fopen(out, "w");
fprintf(fo, "%d\n", n); for (; n > 0; n)
17
fprintf(fo, "%d\n", rand()%(M 1) + 1); fclose(fo);
}
Bài tập
Viết các hàm sau:
1.
Tạo mảng 1 chiều số nguyên a (giá trị ngẫu nhiên < 100) có
kích thước n (0 • Dòng đầu tiên lưu giá trị n • Dòng tiếp theo lưu các phần tử của mảng cách nhau bởi khoảng trắng 2. Đọc mảng 1 chiều từ file “mang.inp” và sắp xếp mảng theo thứ
tự tăng dần. Lưu vào file “sapxep.out” theo cấu trúc tương tự câu
1. 18 Cho file “test.inp” có cấu trúc như sau • Dòng đầu tiên là số nguyên n • Dòng tiếp theo là n giá trị nguyên cách nhau bởi khoảng trắng Hãy viết các hàm tìm phần tử có giá trị lớn nhất, phần tử nhỏ
nhất, số lượng phần tử chẵn, lẻ. Sau đó lưu vào file “kq.out” gồm
các dòng sau: • Dòng 1: So lon nhat la: … • Dòng 2: So nho nhat la: … • Dòng 3: So phan tu chan la: … • Dòng 4: So phan tu le la: … 19 ́ STT TÊN HA M̀ VI DÚ ̃ Ử
Y NGHI A S
DUNG̣ ̣ ĐOC TÂP TIN ̣ ̣ ̉ ́ơ
̀
(cid:0) ptr: vu ng nh đê
̃
ư ư
l u d liêu đoc
́ươ
́
́ 1 fread(&ptr, size, len, FILE *) ̃
̀ ̣ ̣ ̃
ư int a[30], b, n;
fread(a,
sizeof(int), n , f);
Fread(&b,
sizeof(int), 1 , f); ̀ (cid:0) ̣ ̣ ̣ ́ ươ ng t ự 1 fwrite(&prt, size, len, FILE *) (cid:0) size: ki ch th
c
́
ơ
mô i ô nh (ti nh
bă ng byte)
̀
len: đô da i d liêu
câ n đoc
GHI TÂP TIN
Tham sô t
̀ư
nh ha m fread fwrite(a,
sizeof(int), n , f); 20 ̣ Kiểm tra vị trí cuối cùng trong File • Cú pháp: int feof(FILE *f) • Trả về EOF nếu cuối tập tin • Ngược lại trả về 0 Di chuyển con trỏ về vị trí đầu File • Cú pháp: void rewind(FILE *f) 21 int fread (void *p, int size , int n, FILE *fp); • p: con trỏ trỏ tới vùng nhớ chứa dữ liệu đọc được • size: kích thước của mẫu tin (byte) • n: là số mẫu tin cần đọc • fp: là con trỏ file Hàm sẽ trả về một giá trị = số mẫu tin thực sự đọc được 23 int fwrite (void *p, int size , int n , FILE *fp); • p: con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi • size: kích thước của mẫu tin (byte) • n: số mẫu tin cần ghi • fp: con trỏ file Hàm sẽ trả về một giá trị = số mẫu tin thực sự ghi được 24 Viết chương trình phát sinh ngẫu nhiên danh sách các tọa độ điểm
trong mặt phẳng Oxy (Giá trị của mỗi trục tọa độ phát sinh trong
khoảng [-50..50]) • Lưu danh sách này vào file “dsToaDo.inp” • Đọc file “dsToaDo.inp” trên và lưu vào file “toaDoDuong.out” những tọa độ điểm thuộc phần tư thứ nhất 25 26 int main() {
MyPoint *a;
int n;
srand((unsigned int) time(NULL));
printf("So luong toa do can phat sinh: ");
scanf("%d", &n);
a = (MyPoint *) malloc(n * sizeof(MyPoint));
PhatSinh(a, n);
printf("\n***Danh sach toa do duoc phat sinh:\n");
XuatMang(a, n);
LuuFile(a, n, "dsToaDo.inp");
LuuToaDoDuong("dsToaDo.inp", "toaDoDuong.out");
//Kiem tra ket qua luu file
printf("\n***Danh sach toa do trong file:\n");
XuatFile("dsToaDo.inp");
printf("\n***Danh sach toa do duong trong file:\n");
XuatFile("toaDoDuong.out"); free(a);
getch();
return 0;
} • Xóa File remove (đường dẫn tập tin); • Đổi tên File rename (tên tập tin cũ, tên tập tin mới); • Cho biết vị trí con trỏ File ftell (FILE *); 32 fseek (FILE *, độ dời, vị trí xuất phát); Các vị trí: • SEEK_SET đầu tập tin (giá trị 0) • SEEK_END cuối tập tin (giá trị 2) • SEEK_CUR vị trí hiện hành (giá trị 1) Độ dời tính bằng byte 33 Trong bài tập ví dụ về danh sách tọa độ điểm trong mặt phẳng, bổ
sung thêm các hàm thực hiện yêu cầu sau: 1. Nhập một tọa độ điểm từ bàn phím 2. Bổ sung tọa độ điểm này vào cuối file “dsToaDo.inp” 3. Nếu tọa độ điểm vừa nhập có tọa độ thuộc phần tư thứ nhất
thì bổ sung thêm vào cuối file “toaDoDuong.out” 4. Xóa tọa độ điểm d cho trước (nếu có xuất hiện) trong file
“dsToaDo.inp” và “toaDoDuong.out” 34 35Bài tập
Thao tác trên File nhị phân
Các thao tác khác trên File
ĐỌC, GHI KIỂU CẤU TRÚC TRÊN FILE
Đọc kiểu cấu trúc trên file
Ghi kiểu cấu trúc trên file
Ví dụ
Khai báo cấu trúc và hàm
struct structPoint
{
int x;
int y;
};
typedef structPoint MyPoint;
void PhatSinh(MyPoint *a, int n);
void XuatMang(MyPoint *a, int n);
void LuuFile(MyPoint *a, int n, char *fileName);
void LuuToaDoDuong(char *fileIn, char *fileOut);
void XuatFile(char *fileName);
void PhatSinh(MyPoint *a, int n) {
for (int i = 0; i < n; i++) {
a[i].x = rand() % 51 - rand() % 51;
a[i].y = rand() % 51 - rand() % 51;
}
}
void XuatMang(MyPoint *a, int n) {
for (int i = 0; i < n; i++) {
printf("(%d, %d); ", a[i].x, a[i].y);
}
}
void LuuFile(MyPoint *a, int n, char *fileName) {
FILE *fp;
fp = fopen(fileName, "wb");
for (int i = 0; i < n; i++) {
fwrite(&a[i], sizeof(MyPoint), 1, fp);
}
fclose(fp);
}
void LuuToaDoDuong(char *fileIn, char *fileOut) {
FILE *fIn, *fOut;
fIn = fopen(fileIn, "rb");
fOut = fopen(fileOut, "wb");
MyPoint d;
while (fread(&d, sizeof(MyPoint), 1, fIn) > 0) {
if (d.x > 0 && d.y > 0)
fwrite(&d, sizeof(MyPoint), 1, fOut);
}
_fcloseall();
}
void XuatFile(char *fileName) {
FILE *fp;
fp = fopen(fileName, "rb");
MyPoint d;
while (fread(&d, sizeof(MyPoint), 1, fp) > 0) {
printf("(%d, %d); ", d.x, d.y);
}
}
Các thao tác khác trên File
Các thao tác khác trên File
Di chuyển con trỏ File từ vị trí xuất phát cho trước
Bài tập
Q&A