ự ậ

Th c t p K  THU T L P TRÌNH

ữ ệ

ầ Tu n 4­6

: Xây d ng c u trúc d  li u và các ch c năng

ấ ữ ệ

nh p/xu t d  li u

Yêu cầu:

- Xây dựng cấu trúc dữ liệu phù hợp để quản lý đối tượng sinh viên,

gồm các thông tin:

 Mã l pớ

 Mã sinh viên

 H  và tên ọ

 Ngày sinh

ể  Đi m trung bình tích lũy

- Dữ liệu (hồ sơ sinh viên) được ghi trên file.

- Xây dựng các chức năng cho phép nhập hồ sơ, in danh sách đã

nhập.

- Tự động chỉnh sửa chính tả khi nhập họ tên sinh viên.

- Kiểm tra tính hợp lệ của ngày sinh khi nhập. Ngày sinh có dạng dd/mm/yyyy, dd là ngày có giá trị trong khoảng từ 1 đến 31, mm là tháng có giá trị trọng khoảng 1 đến 12 và yyyy là năm có giá trị từ 1900 đến 2016; và dd/mm/yyyy phải là ngày hợp hệ (có trên lịch), ví dụ ngày 30/2/2016 là không hợp lệ.

- Kiểm tra tính hợp lệ của điểm trung bình tích lũy, điểm trung bình

tích lũy >=0 và <=10.

- Các chức năng này được kết hợp trong chương trình đã xây dựng

ở các tuần trước.

Kiến thức liên quan:

A. KIỂU BẢN GHI

ấ ả ộ ớ m t SINH VIÊN v i các thông tin:

1 Khái niệm ể ế ề V n đ : Làm th  nào đ  mô t ố - Mã s  sinh viên;

ỉ ườ ể ng trú ả ặ ồ ọ - H  tên; - Ngày tháng năm sinh; ớ - Gi i tính; ị - Đ a ch  th ế Ho c làm th  nào đ  mô t NGÀY THÁNG bao g m các thông tin:

- Ngày; - Tháng; - Năm ế ầ

ấ ừ ầ ử ụ ườ ậ ữ ệ ữ ể i l p trình  nh ng ki u d  li u đã có

ướ

ấ ầ

ầ ượ ọ ộ ườ ồ ề ng (field).

ể ữ ệ c g i là m t tr ể ầ ử ủ ệ ả ả

ự ể ể ể ả

ể ấ ủ ữ ậ => H u h t các ngôn ng  l p trình trong đó có C/C++ cho phép ng ớ ự ị  đ nh nghĩa ra c u trúc m i theo nhu c u s  d ng t t ị ặ ho c đã đ nh nghĩa tr c đó. ể   ể Ki u c u trúc (Structure) là ki u d  li u bao g m nhi u thành ph n có ki u ỗ khác nhau, m i thành ph n đ ữ S  khác bi t gi a ki u c u trúc và ki u m ng là: các ph n t ầ ử ủ ki u còn các ph n t là c a ki u c u trúc v i 7

ể ấ  c a m ng là cùng  c a ki u c u trúc có th  có ki u khác nhau. Hình  nh sau ớ  tr 1 ể ấ ngườ 3 2 4 5 7 6

ể ạ ả còn ki u m ng có d ng:

0 1 2 3 4 5 6 7 8 9 1 1 1 1 14

0 1 2 3

Cú pháp 1:

ấ struct 

{

ể ườ   ;

ể ườ   ;

……..

ể ườ   ;

};

Cú pháp 2:

typedef struct

{

ể ườ   ;

ể ườ   ;

……..

2

ể ườ   ;

ấ } ;

Trong đó:

ấ ộ ượ ặ ắ ặ ủ ể   c đ t theo quy t c đ t tên c a danh bi u; - : là m t tên đ

ể ấ ẽ tên này mang ý nghĩa s  là tên ki u c u trúc;

ườ ỗ ườ ữ ệ ấ ng i> (i=1..n): m i tr ộ   ng trong c u trúc có d  li u thu c ể -  

ủ ể ườ ả ộ ượ ặ ắ ặ ki u gì (tên c a tr ng ph i là m t tên đ c đ t theo quy t c đ t tên

ể ủ c a danh bi u).

ể ể ả ộ ủ Ví d  1ụ : Đ  qu n lý ngày, tháng, năm c a m t ngày trong năm ta có th  khai báo

ể ấ ồ ki u c u trúc g m 3 thông tin: ngày, tháng, năm.

struct KieuNgayThang  {

unsigned char Ngay;  unsigned char Thang;  unsigned int Nam;

};  typedef struct  {

unsigned char Ngay;  unsigned char Thang;  unsigned int Nam;

ầ ỗ ượ ả ở ố } KieuNgayThang;  Ví d  2ụ : M i sinh viên c n đ c qu n lý b i các thông tin: Mã s  sinh viên, h ọ

ớ ỉ ườ ể tên, ngày tháng năm sinh, gi ị i tính, đ a ch  th ng trú. Lúc này ta có th  khai báo

ộ ồ m t struct g m các thông tin trên.

struct KieuSinhVien  {  char MSSV[10];  char HoTen[40];  struct KieuNgayThang NgaySinh;  int Phai;  char DiaChi[40];

3

};

typedef struct  {  char MSSV[10];  char HoTen[40];  KieuNgayThang NgaySinh;  int Phai;  char DiaChi[40];  } KieuSinhVien;

ỗ ầ ộ o

ồ   ế M i thành ph n gi ng là m t bi n riêng thu c c u trúc, nó g m ầ ấ ộ ượ ọ ườ ể ầ ộ ố ki u và tên thành ph n. M t thành ph n cũng còn đ c g i là tr ng.

ầ ủ ể ấ o

ể ả ố ầ ặ   ế Ph n tên c a ki u c u trúc và ph n danh sách bi n có th  có ho c ấ   ự ế  k t thúc cu i cùng ph i là d u

ẩ ấ không. Tuy nhiên trong khai báo kí t ch m ph y (;).

ượ c phép khai báo l ng nhau, nghĩa là m t thành o

ầ ủ ể ạ ồ ộ ườ ể ấ Các ki u c u trúc đ ể ấ ph n c a ki u c u trúc có th  l ộ ể ấ ng có ki u c u trúc. i là m t tr

ẽ ượ o

ấ ể M t bi n có ki u c u trúc s  đ ượ ắ ứ ự ấ ộ ệ ự ộ ế ệ ủ th c hi n c a nó đ ấ ụ c s p liên t c theo th  t ớ c c p phát b  nh  sao cho các      xu t hi n trong khai báo.

ế ấ ệ ươ ự ư ế ộ 2. Khai báo biến cấu trúc Vi c khai báo bi n c u trúc cũng t ng t ể ữ ệ    nh  khai báo bi n thu c ki u d  li u

chu n. ẩ

Cú pháp:

ố ớ ấ ượ ị c đ nh nghĩa theo cách 1: - Đ i v i c u trúc đ

ế ế ấ struct   [, …];

ố ớ ấ ượ ị c đ nh nghĩa theo cách 2: - Đ i v i các c u trúc đ

ế ấ ế   [, …];

ế ế ấ ể Ví dụ: Khai báo bi n NgaySinh có ki u c u trúc KieuNgayThang; bi n SV có

ể ấ ki u c u trúc KieuSinhVien.

struct KieuNgayThang NgaySinh;  struct KieuSinhVien SV;  KieuNgayThang NgaySinh;  KieuSinhVien SV;

4

ấ ế ừ ế ấ ủ ng c a bi n c u trúc

3. Các thao tác trên biến kiểu cấu trúc ườ Truy xu t đ n t ng tr Cú pháp:

ế ấ ườ .;

ử ụ ế ể ấ Khi   s ấ     d ng   cách   truy   xu t   theo   ki u   này,   các   thao   tác   trên  

ườ ữ ệ ủ ư ế ể ố trúc>. gi ng nh  các thao tác trên các bi n c a ki u d  li u c a

ườ .

ế ươ ữ ệ ừ ọ ế ẩ Ví d 1ụ : Vi t ch ng trình cho phép đ c d  li u t bàn phím cho bi n m u tin

ế ẩ SinhVien và in bi n m u tin đó lên màn hình:

#include  #include  #include  typedef struct  {      unsigned char Ngay;      unsigned char Thang;      unsigned int Nam;  } KieuNgayThang;  typedef struct  {      char MSSV[10];      char HoTen[40];      KieuNgayThang NgaySinh;      int Phai;      char DiaChi[40];  } KieuSinhVien;  /* Hàm in lên màn hình 1 m?u tin SinhVien*/

void InSV(KieuSinhVien s)  {      printf(“MSSV: | Ho va ten | Ngay Sinh | Dia chi\n”); printf(“%s   |   %s   |   %d­%d­%d   |   %s\n”,s.MSSV,s.HoTen,

s.NgaySinh.Ngay,s.NgaySinh.Thang,s.NgaySinh.Nam,s.DiaChi);

5

}  int main()  {      KieuSinhVien SV, s;      printf(“Nhap MSSV: “);gets(SV.MSSV);      printf(“Nhap Ho va ten: “);gets(SV.HoTen);      printf(“Sinh ngay: “);scanf(“%d”,&SV.NgaySinh.Ngay);      printf(“Thang: “);scanf(“%d”,&SV.NgaySinh.Thang);      printf(“Nam: “);scanf(“%d”,&SV.NgaySinh.Nam);      printf(“Gioi tinh (0: Nu), (1: Nam): “);scanf(“%d”,&SV.Phai);      fflush(stdin);      printf(“Dia chi: “);gets(SV.DiaChi);      InSV(SV);      s=SV;       InSV(s);      getch();      return 0;  } L u ýư :

ự ể ế ấ ấ - Các bi n c u trúc có th  gán cho nhau. Th c ch t đây là thao tác trên

ộ ấ ả ộ ườ ẽ toàn b  c u trúc không ph i trên m t tr ng riêng r nào. Ch ươ   ng

ộ ụ trình trên dòng s=SV là m t ví d ;

ể ự ệ ế ể ấ ớ ượ c các thao tác - V i các bi n ki u c u trúc ta không th  th c hi n đ

sau đây:

ế ấ ử ụ ậ  S  d ng các hàm xu t nh p trên bi n c u trúc; ấ

ố ọ ệ  Các phép toán quan h , các phép toán s  h c và logic.

ủ ứ ậ ố ổ ế ằ ứ Ví d  2ụ : Nh p vào hai s  ph c và tính t ng c a chúng. Ta bi ố   t r ng s  ph c là

ố ự ộ ặ ầ ả ự ầ ọ m t c p (a,b) trong đó a, b là các s  th c, a g i là ph n th c, b là ph n  o. (Đôi

ườ ế ố ứ ướ ạ ộ ơ ị ả khi ng i ta cũng vi t s  ph c d i d ng a + ib trong đó i là m t đ n v   o có

ọ ố ủ ứ ổ tính ch t iấ 2=­1). G i s  ph c c1=(a1, b1) và c2=(a2,b2) khi đó t ng c a hai s ố

ộ ố ứ ứ ể ớ ế ph c c1 và c2 là m t s  ph c c3 mà c3=(a1+a2, b1+b2). V i hi u bi ư ậ   t nh  v y

ộ ấ ỗ ố ể ườ ộ ườ ứ ta có th  xem m i s  ph c là m t c u trúc có hai tr ng, m t tr ễ   ể ng bi u di n

6

ộ ườ ự ầ ầ ả ủ ệ ễ ể ổ cho ph n th c, m t tr ng bi u di n cho ph n  o. Vi c tính t ng c a hai s ố

ứ ượ ự ộ ầ ả ự ấ ằ ầ ầ ớ ph c đ ộ   c tính b ng cách l y ph n th c c ng v i ph n th c và ph n  o c ng

ầ ả ớ v i ph n  o.

#include  #include  #include  typedef struct  {      float Thuc;      float Ao;  } SoPhuc;  /* Ham in so phuc len man hinh*/  void InSoPhuc(SoPhuc p)  {      printf(“%.2f + i%.2f\n”,p.Thuc,p.Ao);  }  int main()  {      SoPhuc p1,p2,p;      printf(“Nhap so phuc thu nhat:\n”);      printf(“Phan thuc: “);scanf(“%f”,&p1.Thuc);      printf(“Phan ao: “);scanf(“%f”,&p1.Ao);      printf(“Nhap so phuc thu hai:\n”);      printf(“Phan thuc: “);scanf(“%f”,&p2.Thuc);      printf(“Phan ao: “);scanf(“%f”,&p2.Ao);      printf(“So phuc thu nhat: “);      InSoPhuc(p1);      printf(“So phuc thu hai: “);      InSoPhuc(p2);      p.Thuc = p1.Thuc+p2.Thuc;      p.Ao = p1.Ao + p2.Ao;      printf(“Tong 2 so phuc: “);      InSoPhuc(p);      getch();

7

return 0;  } ở ạ ấ ở ạ ệ ể ượ ự ệ ế ấ Kh i t o c u trúc  ấ Vi c kh i t o c u trúc có th  đ c th c hi n trong lúc khai báo bi n c u trúc.

ườ ủ ấ ượ ượ ạ ữ ấ Các tr ng c a c u trúc đ ở ạ c kh i t o đ c đ t gi a 2 d u { và }, chúng đ ượ   c

ở ấ ẩ phân cách nhau b i d u ph y (,).

ở ạ ụ ế ấ Ví d : Kh i t o bi n c u trúc NgaySinh:

struct KieuNgayThang NgaySinh ={29, 8, 1986};

ỏ ể ế ệ ấ ộ ươ ự ư 4. Con trỏ cấu trúc Khai báo  Vi c khai báo m t bi n con tr  ki u c u trúc cũng t ng t nh  khi khai báo

ế ặ ấ ỏ ộ ướ ế m t bi n con tr  khác, nghĩa là đ t thêm d u * vào phía tr c tên bi n.

Cú pháp:

ế ấ ỏ struct  * ;

ỏ ấ ư ể ể ộ Ví dụ: Ta có th  khai báo m t con tr  c u trúc ki u NgayThang nh  sau:

struct NgayThang *p;

/* NgayThang *p; // Nếu có định nghĩa kiểu */

ỏ ể ấ ỏ ấ ỉ ụ ể ỏ ư ế ế ị ử ụ S  d ng các con tr  ki u c u trúc  Khi khai báo bi n con tr  c u trúc, bi n con tr  ch a có đ a ch  c  th . Lúc này

ỉ ớ ượ ấ ể ư ữ ị ượ nó ch  m i đ c c p phát 2 byte đ  l u gi ỉ  đ a ch  và đ ậ c ghi nh n là con tr ỏ

ỉ ế ỉ ế ố ượ ư ấ ụ ể ư ch  đ n 1 c u trúc, nh ng ch a ch  đ n 1 đ i t ố ng c  th . Mu n thao tác trên

ỏ ấ ợ ệ ươ ự ư ả con tr  c u trúc h p l , cũng t ng t ỏ  nh  các con tr  khác, ta ph i:

ử ụ ấ ộ ớ - C p phát m t vùng nh  cho nó (s  d ng hàm malloc() hay calloc);

ế ấ ỉ ủ ả ặ ộ ị - Ho c, cho nó qu n lý đ a ch  c a m t bi n c u trúc nào đó.

ị ủ ấ ở ạ Ví dụ: Sau khi kh i t o giá tr  c a c u trúc:

struct NgayThang Ngay = {29,8,1986};

p = &Ngay;

ứ ị ỉ ủ ế ỏ lúc này bi n con tr  p đã ch a đ a ch  c a Ngay.

ầ ủ ấ ậ ượ ả Truy c p các thành ph n c a c u trúc đang đ ỏ ở c qu n lý b i con tr

8

ế ừ ể ậ ườ ủ ấ ỏ ủ Đ  truy c p đ n t ng tr ng c a 1 c u trúc thông qua con tr c a nó, ta s ử

ử ấ ấ ấ ẫ ụ d ng toán t ể ử ụ    d u mũi tên (­>: d u ­ và d u >). Ngoài ra, ta v n có th  s  d ng

ữ ệ ể ậ ượ ả ế đ n phép toán * đ  truy c p vùng d  li u đang đ ỏ ấ   ở c qu n lý b i con tr  c u

ể ấ ầ ế trúc đ  l y thông tin c n thi t.

ử ụ ỏ ấ Ví dụ: S  d ng con tr  c u trúc.

#include  #include  typedef struct  {      unsigned char Ngay;      unsigned char Thang;      unsigned int Nam;  } NgayThang;  int main()  {      NgayThang Ng={29,8,1986};      NgayThang *p;      p=&Ng;      printf(“Truy cap binh thuong %d­%d­%d\n”,      Ng.Ngay,Ng.Thang,Ng.Nam);      printf(“Truy cap qua con tro %d­%d­%d\n”,      p­>Ngay,p­>Thang,p­>Nam);      printf(“Truy cap qua vung nho con tro %d­%d­%d\n”,      (*p).Ngay,(*p).Thang,(*p).Nam);      getch();      return 0;  }

ấ ử ụ ố ố ủ ư

ế

ể ấ ả ề ự

ớ ố ố ử ụ ấ ử ạ   ỏ ấ ­ Cho phép s  d ng c u trúc, con tr  c u trúc là đ i s  c a hàm nh  các lo i bi n khác ­ Cho phép hàm xây d ng tr  v  là ki u c u trúc Ví d  : X  lý danh sách sinh viên, s  d ng hàm v i đ i s  là c u trúc

ụ #include  #include  //Ngay thang

9

struct Ngaythang { int ng ; int th ; int nam ; }; //Sinh vien struct Sinhvien { char hoten[25] ; Ngaythang ns; int gt; float diem ; } ; //cac ham xu ly int sua(Sinhvien &r) ; int in(Sinhvien x) ; int nhap(Sinhvien *p) ; int nhapds(Sinhvien *a, int n) ; int suads(Sinhvien *a, int n) ; int inds(const Sinhvien *a, int n) ; // struct Sinhvien a[10];

int main() {

nhap(a); in(a[1]); // // sua(a[1]);

nhapds(a,9); suads(a,9); inds(a,9); getch(); return 0;

} ///trien khai cac ham int sua(Sinhvien &r)

10

{  int chon;  do {

printf("1:   Sua   ho   ten\n2:   Sua   ngay   sinh\n3:Sua   gioi   tinh\n4:Sua

diem\n5:In\n0: Ket thuc\n");

scanf("%d",&chon); switch (chon) {

case 1:

printf("Nhap ho ten:");  scanf("%s",r.hoten);  break;

case 2:

printf("Nhap ngay thang nam sinh:");  scanf("%d%d%d",&r.ns.ng,&r.ns.th,&r.ns.nam);  break;

case 3:

printf("Nhap gioi tinh 0:Nu 1:Nam:");  scanf("%d",&r.gt) ;  break;

case 4:

printf("Nhap diem:");  scanf("%f",&r.diem);  break;

case 5:

printf("Sinh vien:");  in(r);  break;

case 0:

break;

default:

printf("Nhap gia tri khong dung\n"); break;

}

} while (chon) ;

11

return 0; } //////// int in(Sinhvien x) {  printf("Ho   ten   :%s\nNgay   sinh   %d/%d/%d\n",x.hoten,x.ns.ng,   x.ns.th,

x.ns.nam) ;

printf("Gioi tinh :%s\nDiem :%f\n",(x.gt==1) ?"Nam" :"Nu",x.diem) ; return 0; }

/////// int nhap(Sinhvien *p)  {

printf("Nhap ho va ten: "); scanf("%s",p­>hoten); printf("Nhap ngay sinh (ngay thang nam): "); scanf("%d%d%d", &p­>ns.ng ,&p­>ns.th,&p­>ns.nam); printf("Gioi tinh 0: nu, 1: nam: "); scanf("%d",& p­>gt); printf("Diem: "); scanf("%f",& p­>diem); return 0;

} ////// int nhapds(Sinhvien *a, int n)  {         for (int i=1; i<=n; i++) nhap(&a[i]) ;   return 0; }  ///// int suads(Sinhvien *a, int n)  {       int chon;

12

do      {          printf("\nNhap phan tu duoc su tu 1 den %d, gia tri khac thoat:",n);          scanf("%d",&chon);          if(chon>0 &&chon<=n)          {               sua(a[chon]) ;           }      }while(chon>0 && chon<=n);      return 0; }  ////////// int inds(const Sinhvien *a, int n)  {      for (int i=1; i<=n; i++)          in(a[i]) ;      return 0; }

ườ 5. Cấu trúc với thành phần kiểu bit a. Tr ng bit

ể ế ữ ậ

Đ  ti ườ ư ớ ố ượ ụ ộ ng bit xác đ nh không ph  thu c vào s  l

ẩ ệ ữ t ki m trong l u tr , trong ngôn ng  l p trình C cho phép khai báo   ố ượ   ị ủ ấ ng c a c u trúc v i s  l các tr ng ể ữ ệ bit các ki u d  li u chu n.

ộ ườ ấ ố M t tr ộ ng bit là m t khai báo tr

ườ ộ ớ ượ

ủ ấ ườ ể ợ

ư ế ệ ằ ơ ng int và thêm d u: cùng s  bit n theo ụ sau, trong đó 0 ≤ n < 15. Ví d  do đ  l n c a ngày không v t quá 31, tháng ng này trong c u trúc ngày tháng có th  khai báo không vu t quá 12 nên 2 tr ti t ki m h n b ng 5 và 4 bit nh  sau:

struct Date {   int ng: 5;   int th: 4;   int nam:14;   } ;  ặ ể b. Đ c đi m

ộ ấ ủ ứ ể ặ ầ ườ C n chú ý các đ c đi m sau c a m t c u trúc có ch a tr ng bit:

13

ượ ố ụ − Các bit đ c b  trí liên t c trên dãy các byte.

ườ ả ặ ể − Ki u tr ng bit ph i là int (signed ho c unsigned).

ỗ ườ ộ − Đ  dài m i tr ng bit không quá 16 bit.

ộ ố ỏ ố ể ỏ ế ườ ụ − Có th  b  qua m t s  bit n u b  tr ng tên tr ng, ví d :

struct tu {

int: 8;

int x:8;

}

ỗ ế ỏ

ế ộ ử ụ   m i m t bi n c u trúc theo khai báo trên g m 2 byte, b  qua không s  d ng ấ byte th p và tr ấ ồ ườ ng x chi m byte (8 bit) cao.

ỉ ủ ể ấ ầ ị − Không cho phép l y đ a ch  c a thành ph n ki u bit.

ự ượ ể ả ể − Không th  xây d ng đ c m ng ki u bit.

ụ ế ầ ộ c tr

ộ   ể  hàm m t thành ph n ki u bit. Ví d  n u b là m t ệ ả ề ừ  v  t ế ấ ượ ầ ủ ể − Không đ thành ph n c a bi n c u trúc x có ki u bit thì câu l nh sau là sai:

return x.b ;    // sai

ụ ư ế ể tuy nhiên có th  thông qua bi n ph  nh  sau:

int tam = x.b ; return tam ;  ế ệ ộ ớ t ki m b  nh − Ti

ể ấ ủ ộ ừ ể ụ ầ ể    (xem ví d  trong ph n ki u

− Dùng trong ki u union đ  l y các bit c a m t t h p). ợ

6. Câu lệnh typedef

ậ ể ườ ể ượ ạ c NSD t o m i s ớ ẽ

ử ụ ằ ệ ộ ệ ượ ng các ki u đ Đ  thu n ti n trong s  d ng, thông th ư ể c gán cho m t tên ki u b ng câu l nh typedef nh  sau: đ

ể ể typedef   ;

ự ứ ụ ể ỉ ị ấ   Ví d : Đ  t o ki u m i có tên Bool và ch  ch a giá tr  nguyên (th c ch t

ỉ ầ ể ạ ị ớ ể ch  c n 2 giá tr  0, 1), ta có th  khai báo:

typedef int Bool;

ư ể ố khai báo này cho phép xem Bool nh  ki u s  nguyên.

ể ặ ể ặ ớ ho c có th  đ t tên cho ki u ngày tháng là Date v i khai báo sau:

typedef struct Date {    int ng;    int th;    int nam;

14

};

ể ử ụ ụ ể ể   khi đó ta có th  s  d ng các tên ki u này trong các khai báo (ví d  tên ki u

ả ạ ị ủ ố ủ c a đ i, c a giá tr  hàm tr  l i …).

7. Hàm sizeof()

ộ ặ ế ướ ủ ụ ể i kích th c c a m t bi n ho c ki u. Ví d :

ầ ử ủ ả ạ Hàm tr  l  Bool a, b;   Date x, y, z[50];  printf("%d,%d,%d",sizeof(a),sizeof(b),sizeof(Bool)) ;     // in 2,2,2  ố printf("S  ph n t  c a z =%d ",sizeof(z) / sizeof(Date));  // in 50

B. LÀM VIỆC VỚI FILE

I. Một số khái niệm ữ ệ ươ ượ ư ế D  li u trong ch ng trình đ c l u tr ữ ở ế    RAM máy tính, vì th  khi k t

ươ ắ ữ ệ ẽ ị ả ữ ệ ể ử ầ thúc ch ng trình, t t máy d  li u s  b  gi ả   i phóng. Đ  x  lý d  li u c n ph i

ứ ữ ộ ớ ướ ạ ậ ợ ư l u tr  trên b  nh  ngoài (đĩa c ng, USB, …) d i d ng file. File là t p h p các

ụ ượ ư ữ ượ ử ọ ươ byte liên t c đ c l u tr và đ c gán tên g i. Khi x  lý file ch ng trình có

ữ ứ ử ể ỗ ớ ớ   th  xem xét chu i byte v i cách nhìn khác nhau, có nh ng  ng x  khác nhau v i

ỗ ợ ệ ể ả ớ ớ ữ ệ d  li u. Trong C h  tr  vi c thao tác v i file v i quan đi m: file văn b n, file

ị nh  phân.

ạ ậ ể ả ự lên đĩa. o File văn b n (Text File): là lo i t p tin dùng đ  ghi các ký t

ể ặ ệ ủ ậ ữ ệ ượ ư ữ ỗ Đi m đ c bi t là 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’; ký t này là s ự

ự ề ầ ế ợ ủ k t h p c a 2 ký t CR (Carriage Return ­ V  đ u dòng, mã Ascii là 13) và LF

ỗ ậ ố ượ ế ở (Line Feed ­ Xu ng dòng, mã Ascii là 10). 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).

ấ ậ ể ể ể ả ấ ỉ ầ   Truy xu t t p tin theo ki u văn b n ch  có th  truy xu t theo ki u tu n

t . ự

ệ ử ụ ể ậ ậ ị ớ   o T p tin nh  phân: Quan đi m t p tin là dãy byte liên t c, vi c x  lý v i

ệ ọ ự ậ t p tin d a trên vi c đ c ghi dãy byte.

15

ế ậ ể ạ ệ ế ể ộ ộ Bi n t p tin: ữ ệ ậ 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. D  li u ch a trong m t t p tin đ ớ   c truy xu t qua các thao tác v i

ế ậ ệ ạ ậ ố thông s  là bi n t p tin đ i di n cho t p tin đó.

ỏ ậ ượ ệ ở ạ Con tr t p tin: ộ ậ Khi m t t p tin đ ể c m  ra đ  làm vi c, t ờ   ỗ i m i th i

ủ ậ ộ ị ẽ ể ạ ẽ ả ệ ọ đi m, s  có m t v  trí c a t p tin mà t i đó vi c đ c/ghi thông tin s  x y ra.

ườ ỉ ế ặ ộ ỏ ị Ng i ta hình dung có m t con tr  đang ch  đ n v  trí đó và đ t tên nó là con tr ỏ

ậ t p tin.

ữ ệ ỏ ẽ ể ọ ộ ị Sau khi đ c/ghi xong d  li u, con tr  s  chuy n d ch thêm m t ph n t ầ ử

ố ậ ầ ử ữ ệ ế ấ ố ề v  phía cu i t p tin. Sau ph n t ủ ậ    d  li u cu i cùng c a t p tin là d u k t thúc

ậ t p tin EOF (End Of File).

ớ ậ II. Các thao tác trên tập tin Các thao tác v i t p tin:

ế ậ

1

o Khai báo bi n t p tin.

ở ậ

2

ằ o M  t p tin b ng hàm fopen().

ủ ậ ữ ệ ử ự ệ ằ

3

o Th c hi n các thao tác x  lý d  li u c a t p tin b ng các hàm

ữ ệ ọ đ c/ghi d  li u.

4

ằ o Đóng t p tin b ng hàm fclose().

Ở ờ ượ ị ớ ậ  đây, ta thao tác v i t p tin nh  các hàm đ ư ệ   c đ nh nghĩa trong th  vi n

stdio.h.

1. Khai báo biến tập tin 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;

2. Mở tập tin Cú pháp

FILE *fopen(char *Path, const char *Mode)

Trong đó:

16

ỉ ườ ỗ ế ậ ẫ ­ 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 . Các giá tr  có th  c a

Mode:

Chế Ý nghĩa

ể ọ

ả ậ ớ ể

ả M  t p tin văn b n đ  đ c  T o ra t p tin văn b n m i đ  ghi  N i vào t p tin văn b n

ả ể ọ ể ậ ị

ị ị T o ra t p tin nh  phân đ  ghi  N i vào t p tin nh  phân

ể ọ ả

ể ọ ậ ả

ở ậ ạ ố ở ậ ạ ậ ố ở ộ ậ ạ ố ớ ậ ả đ  ộ r  w  ậ a  rb  M  t p tin nh  phân đ  đ c  wb  ab  r+  M  m t t p tin văn b n đ  đ c/ghi  w+  a+ T o ra t p tin văn b n đ  đ c ghi  ạ 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

ớ ậ ị ở ạ ế ế ặ ơ ị M c đ nh là m  d ng text n u không có xác đ nh là b, n u rõ ràng h n thì thêm

ể ể ỉ ị ị ch  đ nh t đ  xác đ nh là ki u text.

ả ề ộ ỏ ậ ươ ủ ể ­ Hàm fopen tr  v  m t con tr  t p tin. Ch ng trình c a ta không th  thay

ị ủ ộ ỗ ế ở ậ ệ ấ ỏ ổ đ i giá tr  c a con tr  này. N u có m t l i xu t hi n trong khi m  t p tin thì

ả ề ỏ hàm này tr  v  con tr  NULL.

ở ộ ậ ụ ể Ví d : M  m t t p tin tên TEST.txt đ  ghi.

ớ ậ ệ ể

FILE *f;  f = fopen("c:\\TEST.txt", "w");  if (f!=NULL)  {  /* Các câu l nh đ  thao tác v i t p tin*/  /* Đóng t p tin*/  }  ể ỏ ớ ị ị ượ ệ ự Ki m tra con tr f v i giá tr  NULL cho phép xác đ nh đ ệ   c l nh th c hi n

thành công hay không?

17

ở ậ ế ể ườ ợ ậ ồ ạ ồ ẽ ị ậ N u m  t p tin đ  ghi, tr ng h p t p tin đã t n t i r i thì t p tin s  b  xóa và

ộ ậ ớ ượ ạ ố ữ ệ ả ử ụ ế ố m t t p tin m i đ c t o ra. N u ta mu n ghi n i d  li u, ta ph i s  d ng ch ế

ế ộ ọ ả ồ ạ ồ ở ớ ế ậ ộ đ  “a”. Khi m  v i ch  đ  đ c, t p tin ph i t n t i r i, n u không m t l ộ ỗ ẽ i s

ệ ấ xu t hi n.

3. Đóng tập tin

ượ ể ậ ượ ở ở Hàm fclose() đ c dùng đ  đóng t p tin đ c m  b i hàm fopen(). Hàm này

ạ ệ ậ ạ ậ ữ ệ ẽ s  ghi d  li u còn l i trong vùng đ m vào t p tin và đóng l i 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(). Giá tr  tr  v  c a hàm

ả ề ệ ế ậ ằ ấ ệ   là 0 báo r ng vi c đóng t p tin thành công. Hàm tr  v  EOF n u có xu t hi n

l i. ỗ

ể ử ụ ể ấ ả ậ ạ Ngoài ra, ta còn có th  s  d ng hàm fcloseall() đ  đóng t t c  các t p tin l i.

Cú pháp: int fcloseall()

ả ả ề ủ ế ậ ố ượ ạ ế K t qu  tr ổ  v  c a hàm là t ng s  các t p tin đ c đóng l i. N u không

ả ả ề ế thành công, k t qu  tr  v  là EOF.

4. Kiểm tra đến cuối tập tin hay chưa? Cú pháp: int feof(FILE *f)

ể ạ ớ ố ậ ư ả ề Ý nghĩa: Ki m tra xem đã ch m t i cu i t p tin hay ch a và tr ế    v  EOF n u

ố ậ ượ ớ ượ ạ ả ề cu i t p tin đ ạ c ch m t i, ng i tr  v  0. c l

5. Di chuyển con trỏ tập tin về đầu tập tin - Hàm rewind()

ề ầ ậ ử ụ ể ­ Chuy n v  đ u t p tin, s  d ng hàm rewind().

Cú pháp: void rewind(FILE *f);

ỏ ậ + f: con tr  t p tin đang thao tác.

ấ ỳ ử ụ ể ế ị ­ Chuy n đ n v  trí b t k  s  d ng hàm fseek().

Cú pháp: int fseek(FILE *f, long offset, int whence);

ỏ ậ + f: con tr  t p tin đang thao tác.

ỏ ậ ể ầ ố ị + offset: s  byte c n d ch chuy n con tr  t p tin.

ắ ầ ể ể ả ị ị + whence: v  trí b t đ u đ  tính kho ng cách d ch chuy n cho offset:

18

ị SEEK_SET ầ ậ V  trí đ u t p tin 0

ệ ạ ủ ị SEEK_CUR V  trí hi n t ỏ ậ   i c a con tr  t p 1

ố ậ SEEK_END tin  ị V  trí cu i t p tin 2

ả ả ề ủ ế ệ ể ế ế + K t qu  tr  v  c a hàm là 0 n u vi c di chuy n thành công. N u không

ỗ ượ ị thành công, 1 giá tr  khác 0 (đó là 1 mã l i) đ ả ề c tr  v .

ị ủ ấ ỏ ị ­ L y v  tr  c a con tr  file hàm ftell();

Cú pháp: long ftell(FILE *stream);

ế ệ ạ + stream: bi n đ i di n cho file

ả ề ị ớ ầ ủ ỏ + tr  v  v  trí c a con tr  file so v i đ u file

III. Truy cập tập tin văn bản

1. Ghi dữ liệu lên tập tin văn bản

1.1 Hàm fputc()

ượ ể ộ ự ộ ậ ả Hàm này đ c dùng đ  ghi m t ký t lên m t t p tin văn b n đang đ ượ   c

ở ể ệ m  đ  làm vi c.

Cú pháp: int fputc(int c, FILE *f)

ủ ố ộ ự ượ ứ Trong đó, tham s  c ch a mã Ascii c a m t ký t nào đó. Mã này đ c ghi

ế ớ ả ề ặ ỗ ế ậ ỏ lên t p tin liên k t v i con tr  f. Hàm này tr  v  EOF n u g p l i.

1.2 Hàm fputs()

ể ộ ỗ ự ứ ậ Hàm này dùng đ  ghi m t chu i ký t ệ  ch a trong vùng đ m lên t p tin văn

b n. ả

Cú pháp: int fputs(const char *buffer, FILE *f)

ỉ ế ủ ể ầ ỗ ỏ ị Trong đó, buffer là con tr  có ki u char ch  đ n v  trí đ u tiên c a chu i ký

ỗ ỗ ả ề ứ ế ị t ự ượ  đ c ghi vào. Hàm này tr  v  giá tr  0 n u buffer ch a chu i r ng và tr  v ả ề

ặ ỗ ế EOF n u g p l i.

1.3 Hàm fprintf()

ữ ệ ể ậ ạ ả ị Hàm này dùng đ  ghi d  li u có đ nh d ng lên t p tin văn b n.

19

Cú pháp: fprintf(FILE *f, const char *format, varexpr)

ủ ạ ạ ỗ ớ ố ị ị Trong  đó: format: chu i  đ nh d ng (gi ng v i  các  đ nh d ng c a hàm

ứ ể ể ấ ỗ ẩ   ứ printf()), varexpr: danh sách các bi u th c, m i bi u th c cách nhau d u ph y

(,).

ạ ị Đ nh d ng Ý nghĩa

ố ữ ố ậ ố Ghi s  nguyên  ố ự ữ ố ậ ố %d  %[.s  ch  s  th p phân] f Ghi s  th c có  theo quy

ặ ặ ọ %o  %x  %c  %s  %e   ho c   %E   ho c   %g ố ắ t c làm tròn s .  ệ ố Ghi s  nguyên h  bát phân  ố ệ ậ ụ Ghi s  nguyên h  th p l c phân  ự ộ   Ghi m t ký t ự Ghi chu i ký t ố ự ạ Ghi s  th c d ng khoa h c (nhân 10 mũ x)

ặ ho c %G

ế ươ ỗ ự ậ ụ Ví d : Vi t ch ng trình ghi chu i ký t ả  lên t p tin văn b n D:\\Baihat.txt

#include  #include  int main(){  FILE *f;  clrscr();  f=fopen("D:\\Baihat.txt","w+");  if (f!=NULL){  fputs("Em oi Ha Noi pho.\n",f);  fputs("Ta con em, mui hoang lan; ta con em, mui hoa sua.",f);  fclose(f);  }  getch();  return 0;  }

2. Đọc dữ liệu từ tập tin văn bản

2.1 Hàm fgetc()

20

ữ ệ ừ ậ ể ọ ả ượ Hàm này dùng đ  đ c d  li u t t p tin văn b n đang đ ở ể c m  đ  làm

vi c. ệ

Cú pháp: int fgetc(FILE *f)

ả ề ủ ộ ự ể ả ậ Hàm này tr  v  mã Ascii c a m t ký t nào đó (k  c  EOF) trong t p tin

ế ớ ỏ liên k t v i con tr  f.

2.2 Hàm fgets()

Cú pháp: char *fgets(char *buffer, int n, FILE *f)

ượ ể ọ ỗ ộ ự ừ ậ ả Hàm này đ c dùng đ  đ c m t chu i ký t t p tin văn b n đang đ t ượ   c

ọ ủ ế ớ ế ở ự ặ ặ ỏ m  ra và liên k t v i con tr  f cho đ n khi đ c đ  n ký t ho c g p ký t ự ố    xu ng

ự ượ ỗ ế ư ặ ả ự ế dòng ‘\n’ (ký t này cũng đ c đ a vào chu i k t qu ) hay g p ký t k t thúc

ự ượ ư ỗ ế ả EOF (ký t này không đ c đ a vào chu i k t qu ).

Trong đó:

ớ ủ ớ ỉ ế ệ ể ỏ ứ   ­ buffer (vùng đ m): con tr  có ki u char ch  đ n cùng nh  đ  l n ch a

các ký t ự ậ ượ  nh n đ c.

ấ ủ ỉ ộ ỗ ớ ị ­ n: giá tr  nguyên ch  đ  dài l n nh t c a chu i ký t ự ậ ượ  nh n đ c.

ế ớ ộ ậ ỏ ­ f: con tr  liên k t v i m t t p tin nào đó.

ự ự ộ ượ ỗ ế ả ư ố ­ Ký t NULL (‘\0’) t đ ng đ c thêm vào cu i chu i k t qu  l u trong

vùng đêm.

ả ề ị ỉ ầ ặ ỗ ủ ệ ­ Hàm tr  v  đ a ch  đ u tiên c a vùng đ m khi không g p l ư   i và ch a

ự ế ả ề ị ặ g p ký t k t thúc EOF. Ng ượ ạ c l i, hàm tr  v  giá tr  NULL.

2.3 Hàm fscanf()

ữ ệ ừ ậ ể ọ ả Hàm này dùng đ  đ c d  li u t ế    t p tin văn b n vào danh sách các bi n

ạ ị theo đ nh d ng.

Cú pháp: fscanf(FILE *f, const char *format, varlist)

ỗ ị ạ ố Trong đó: format: chu i đ nh d ng (gi ng hàm scanf()); varlist: danh sách

ế ế ấ ẩ ỗ các bi n m i bi n cách nhau d u ph y (,).

ế ươ ậ ở ậ ụ Ví   d :   Vi t   ch ng   trình   chép   t p   tin   D:\Baihat.txt trên   sang   t p   tin

D:\Baica.txt.

21

#include  #include  int main()  {

FILE *f1,*f2;  clrscr();  f1=fopen("D:\\Baihat.txt","rt");  f2=fopen("D:\\Baica.txt","wt");  if (f1!=NULL && f2!=NULL)  {

int ch=fgetc(f1);  while (! feof(f1))  {

fputc(ch,f2);  ch=fgetc(f1);

}  fcloseall();

}  getch();  return 0;

}

ể ậ ị

ậ ư ầ ậ ừ ươ ủ ầ ấ ậ ng trình, thay vì nh n t

3. Ví dụ ớ ọ Đ c ma tr n tính ma tr n, ghi ma tr n chuy n v  vào file m i. Xem xét file văn ả b n nh  đ u vào, đ u ra c a ch  bàn phím và xu t ra màn hình.

#include  #include  int a[100][100]; int n,m;

int main()  {

char *infile="vao.txt", *outfile="ra.txt"; int i, j; FILE *f1,*f2;

22

f1=fopen(infile,"rt");  if(f1==NULL) {

printf("Loi mo file %s",infile); getch(); return ­1;

} f2=fopen(outfile,"wt");  if(f2==NULL) {

printf("Loi mo file %s",outfile); getch(); fclose(f1); return ­2;

} fscanf(f1,"%d%d",&m,&n); for(i=0;i

for(j=0;j

fscanf(f1,"%d",&a[i][j]);

}

} fprintf(f2,"%d %d\n",n,m); for(i=0;i

for(j=0;j

fprintf(f2,"%4d",a[j][i]);

} fprintf(f2,"\n");

} fclose(f1); fclose(f2); printf("Ket thuc tinh chuyen vi");

23

getch();  return 0;

}

IV. Truy cập tập tin nhị phân

1. Ghi dữ liệu lên tập tin nhị phân Cú pháp: size_t     fwrite(const void *ptr, size_t size, size_t n, FILE *f)

Trong đó:

ỏ ỉ ế ậ ầ ớ ứ ­ ptr: con tr  ch  đ n vùng nh  ch a thông tin c n ghi lên t p tin.

ầ ử ẽ ậ ố ­ n: s  ph n t s  ghi lên t p tin.

ướ ủ ­ size: kích th ỗ c c a m i ph n t ầ ử .

ượ ỏ ậ ­ f: con tr  t p tin đã đ ở c m .

ị ả ề ủ ầ ử ượ ố ậ ị ­ Giá tr  tr  v  c a hàm này là s  ph n t đ ằ   c ghi lên t p tin. Giá tr  này b ng

ệ ỗ ừ ấ n tr  khi xu t hi n l i.

2. Đọc dữ liệu từ tập tin nhị phân

Cú pháp: size_t       fread(const void *ptr, size_t size, size_t n, FILE *f)

Trong đó:

ậ ữ ệ ừ ậ ỏ ỉ ế ớ ẽ ­ ptr: con tr  ch  đ n vùng nh  s  nh n d  li u t t p tin.

ầ ử ượ ọ ừ ậ ố ­ n: s  ph n t c đ c t t p tin. đ

ướ ủ ­ size: kích th ỗ c c a m i ph n t ầ ử .

ượ ỏ ậ ­ f: con tr  t p tin đã đ ở c m .

ị ả ề ủ ầ ử ố ị ­ Giá tr  tr  v  c a hàm này là s  ph n t ọ  đã đ c đ ượ ừ ậ c t t p tin. Giá tr  này

ố ậ ỏ ơ ế ế ạ ặ ỗ ệ ấ ằ b ng n hay nh  h n n n u đã ch m đ n cu i t p tin ho c có l i xu t hi n..

3. Ví dụ

ế ươ ị ố ậ ụ Ví d  1: Vi t ch ự   ng trình ghi lên t p tin CacSo.Dat 3 giá tr  s  (th c,

ố ừ ậ ừ ể ọ ị nguyên, nguyên dài). Sau đó đ c các s  t t p tin v a ghi và hi n th  lên màn

hình.

#include  #include  int main()

24

{  FILE *f;  f=fopen("number.txt","wb");  if (f!=NULL)  {

double d=3.14;  int i=101;  long l=54321;  fwrite(&d,sizeof(double),1,f);  fwrite(&i,sizeof(int),1,f);  fwrite(&l,sizeof(long),1,f);  /* Doc tu tap tin*/  rewind(f);  fread(&d,sizeof(double),1,f);  fread(&i,sizeof(int),1,f);  fread(&l,sizeof(long),1,f);  printf("Cac ket qua la: %f %d %ld",d,i,l);  fclose(f);

} else {

printf("Khong mo duoc file");

ụ ầ ả ấ ỗ ọ }  getch();  return 0;  } Ví d  2: M i sinh viên c n qu n lý ít nh t 2 thông tin: mã sinh viên và h  tên.

ế ươ ự ậ ọ Vi t ch ứ ng trình cho phép l a ch n các ch c năng: nh p danh sách sinh viên t ừ

ọ ữ ệ ừ ậ ậ ồ bàn phím r i ghi lên t p tin SinhVien.dat, đ c d  li u t ồ    t p tin SinhVien.dat r i

ủ ể ộ ọ ị ự   ế hi n th  danh sách lên màn hình, tìm ki m h  tên c a m t sinh viên nào đó d a

ậ ừ vào mã sinh viên nh p t bàn phím.

ấ ằ ầ ử ủ ậ ộ ấ ậ ỗ Ta nh n th y r ng m i ph n t c a t p tin SinhVien.Dat là m t c u trúc có 2

ườ ử ụ ấ ầ ọ tr ng: mã và h  tên. Do đó, ta c n khai báo c u trúc này và s  d ng các hàm

25

ậ ớ ướ ầ ử ủ ậ ỗ ị ọ đ c/ghi t p tin nh  phân v i kích th c m i ph n t c a t p tin là chính kích

ướ ấ th c c u trúc đó.

ườ ữ ữ ệ ơ ư ư ể ợ ị Trong tr ng h p này có th  coi file nh  phân nh  là n i l u tr  d  li u lâu

ữ ệ ơ ư ữ ử ư ể ộ ớ dài, cũng có th  coi nh  là n i l u tr  x  lý d  li u thay vì dùng b  nh .

#include  #include  #include  typedef struct  {

char Ma[10];  char HoTen[40];

} SinhVien;  ///­­­­­­­­­­­ void WriteFile(char *FileName)  {

FILE *f;  int n,i;  SinhVien sv;  f=fopen(FileName,"ab");  printf("Nhap bao nhieu sinh vien? "); scanf("%d",&n);  for(i=1;i<=n;i++)  {

printf("Sinh vien thu %i\n",i);  fflush(stdin); printf(" ­ MSSV: ");gets(sv.Ma);  printf(" ­ Ho ten: ");gets(sv.HoTen);  fwrite(&sv,sizeof(sv),1,f);

}  fclose(f);  printf("Bam phim bat ky de tiep tuc");  getch();

}  void ReadFile(char *FileName)

26

{

FILE *f;  SinhVien sv;  f=fopen(FileName,"rb");  printf(" MSSV | Ho va ten\n");  fread(&sv,sizeof(sv),1,f);  while (!feof(f))  {

printf(" %s | %s\n",sv.Ma,sv.HoTen);  fread(&sv,sizeof(sv),1,f);

}  fclose(f);  printf("Bam phim bat ky de tiep tuc!!!");  getch();

}  void Search(char *FileName)  {

char MSSV[10];  FILE *f;  int Found=0;  SinhVien sv;  fflush(stdin);  printf("Ma so sinh vien can tim: ");gets(MSSV);  f=fopen(FileName,"rb");  while (!feof(f) && Found==0)  {

fread(&sv,sizeof(sv),1,f);  if (strcmp(sv.Ma,MSSV)==0) Found=1;

}  fclose(f);  if (Found == 1)  {

printf("Tim thay SV co ma %s. Ho ten la: %s",sv.Ma,sv.HoTen);

} else

27

{

printf("Tim khong thay sinh vien co ma %s",MSSV);

} printf("\nBam phim bat ky de tiep tuc!!!");  getch();

}  int main()  {  int c;  for (;;)  {  printf("1. Nhap DSSV\n");  printf("2. In DSSV\n");  printf("3. Tim kiem\n");  printf("4. Thoat\n");  printf("Ban chon 1, 2, 3, 4: ");  scanf("%d",&c);  fflush(stdin);

if(c==1)  {

WriteFile("SinhVien.dat");

} else if (c==2)  {

ReadFile("SinhVien.dat");

} else if (c==3) {

Search("SinhVien.Dat");

} else break;  }  return 0;  }

28

ư ệ ộ ố ị Ngoài ra th  vi n stdio.h còn đ nh nghĩa m t s  hàm khác cho phép thao tác

ể ả ầ ợ ớ ậ v i t p tin, sinh viên có th  tham kh o trong ph n tr  giúp.

Kết quả: Chương trình QLSV chạy được theo các yêu cầu đặt ra.

29