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

Bài tập

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

Thao tác trên File nhị phân

́

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

̣

Các thao tác khác trên File

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

ĐỌC, GHI KIỂU CẤU TRÚC TRÊN FILE

Đọc kiểu cấu trúc trên file

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

Ghi kiểu cấu trúc trên file

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

Ví dụ

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

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);

26

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); } }

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; }

Các thao tác khác trên File

• 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

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

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

Bài tập

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

Q&A

35