1. Trang chủ
  2. » Giáo án - Bài giảng

Giáo trình môn kỹ thuật lập trình

124 0 0
Tài liệu được quét OCR, nội dung có thể không chính xác

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 124
Dung lượng 6,75 MB

Nội dung

Trang 2

TAI LIEU THAM KHẢO

Trang 4

PHỤ LỤC B Một số hàm thường dùng trong các thư viện

<stdio.h> Standard Input and Output Library rintf() Xuất dữ liệu theo định dạng ra màn hình scanf() Nhập dữ liệu theo định dạng từ bàn phím ets() Nhập chuỗi ký tự từ bàn phím uts() Xuất chuỗi ký tự ra màn hình getchar() Nhập ký tự từ bàn phím putchar() Xuất ký tự ra màn hình filushQ Xóa bộ đệm bàn phím fopen() Mở file

fclose() Dong file

feof() Kiểm tra kết thúc file

fseek() Dịch chuyên con trỏ file

ftell() Lay vi tri hién thời của con trỏ file

freadQ Đọc khôi dữ liệu từ file

fwrite() Ghi khối dữ liệu ra file

fprintf() Xuất dữ liệu theo định dang ra file

fscanf() Ghi đữ liệu theo định dạng từ file

fgets() Đọc chuỗi ký tự từ file

fputs() Ghi chuỗi ký tự ra file

fgetc() Doc ký tự từ file

fputc() Ghi ký tự ra file

<conio.h> Console Input and Output Library getche() Nhập ký tự, hiển thị ký tự nhập

getch() Nhập ký tự, không hiên thị ký tự nhập <stdlib.h> Standard General Utilities Library

abs() Tính giá trị tuyệt đôi

atoi() Đổi từ chuỗi sang sỐ nguyên

itoa() Đôi từ số nguyên sang ¢ chuỗi srand() Khởi tạo bộ sinh số ngẫu nghiên

rand() Sinh sô ngau nhién

calloc() Cấp phát nhiều vùng nhớ

malloc() Câp phát vùng nhớ

freeO Giải phóng vùng nhớ

exit() Thoát khỏi chương trình

<math.h> Mathematics Library

sqrt() Tính căn bậc 2

powQO Tính lũy thừa

exp() Tính lũy thừa cơ số e

Giáo trình môn Kỹ thuật lập trình

Trang 7

CHƯƠNG 4: KIỄU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

» - Dòng thứ ¡ trong N dòng tiếp theo mỗi dòng có 2 số nguyên Bi và Ci (0 < Bi < Ci)

Trang 8

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

Viết chương trình thực hiện các chức năng sau, mỗi chức năng viết một hàm riêng

a Nhập danh sách các sinh viên và lưu vào file b Đọc dữ liệu từ file và lưu vào mảng

c Xuất danh sách các sinh viên (từ máng) theo dạng bảng d Tìm một sinh viên theo mã sinh viên

e Xuất danh sách các sinh viên có điểm <5

£ Đếm xem có bao nhiêu sinh viên có điểm <5

ø Tính điểm trung bình của các sinh viên có năm sinh 1992

k Xuất các sinh viên có điểm lớn nhất

1 Xóa các sinh viên có điểm = 0

4.3

Viết chương trình thực hiện các công việc sau:

a Nhập và ghi vào file 20 số nguyên bắt kỳ

b Đọc đấy số từ file và tách thành 2 day: day gồm các số lẻ và dãy thành số thực Sau đó

ghi trở lại 2 dãy đã tách vào cùng file đó (ghép vào cuôi file băng kiêu mở file "a")

c Tính tổng dãy và ghi trở lại vào file

4.4 (Trích đề thi Olympic Tin học Sinh viên Toàn quốc 2005, khối thi: Cá nhân Cao

đăng)

Ở miền Trung thường năm nào cũng có những đợt hạn hán nên ông Nam có những thùng

dự trữ nước Do mua làm nhiều đợt nên N (1 <N < 1000) thùng chứa nước của ông Nam

có kích thước khác nhau, mỗi thùng có sức chứa Ci (1 < Ci < 10000,

1 <i<N) Dự đoán rằng năm nay sẽ có đợt hạn hán lớn nên ông Nam muốn đồ đầy nước

hết các thùng để dự trữ Sau khi kiểm tra ông Nam thấy rằng có một số thùng vẫn còn đầy, một số khác thì vơi đi một phần, còn một số thì đã hết Ông quyết định các thùng nào chưa đây thi sẽ chớ đi để đỗ đầy nước Nhưng do nơi lấy nước rất xa, và mỗi lần chỉ chở đi được 1 thùng nên ông quyết định sẽ san nước giữa các thùng với nhau đề số thùng

phải chở đi là ít nhất

Yêu cầu: Cho dung lượng nước hiện có của thùng thứ ¡ là Bi (0 < Bi < C¡, 1 <¡ <N), hãy giúp ông Nam xác định số lượng thùng ít nhất phải mang đi

Dữ liệu: vào từ file văn bản WA TER.INP có dạng sau:

+ Dòng thứ nhất ghi một số tự nhiên N là số lượng các thùng nước

Trang 9

CHƯƠNG 4: KIỂU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA BÀI TẬP CHƯƠNG 4 4.1 Cho danh sách lưu thông tin của các mặt hàng, thông tin gồm: Mã mặt hàng (chuỗi 10 ký tự) Tên mặt hàng (chuỗi 50 ký tự) Số lượng mặt hàng (số nguyên)

Đơn giá mặt hàng (số thực, đơn vị 1000 VNĐ)

Viết chương trình thực hiện các chức năng sau, mỗi chức năng viết một hàm riêng a Nhập danh sách các mặt hàng, lưu ý khi nhập cần kiểm tra trùng mã mặt hàng b Xuất danh sách các mặt hàng theo dạng bảng, và tính thành tiền của từng mặt hàng

STT Mãhàn Ténhang Sốlượng Đơngiá Thành tiền

1 TV Tivi 100 2000 200000

2 TL Tu lanh 200 3000 600000

c Tìm một mặt hàng theo mã mặt hang

đ Xuất danh sách các mặt hàng có số lượng lớn hơn hay bằng 100

e Đếm xem có bao nhiêu mặt hàng có số lượng lớn hơn hay bằng 100 f Tính giá trung bình của các mặt có giá >1.000.000 VND g Xuất các mặt hàng có giá lớn nhất h Xuất các mặt hàng có số lượng nhỏ nhất 1 Cập nhật giảm giá các mặt hàng 10% m Xóa các mặt hàng có số lượng = 0 4.2

Cho danh sách lưu thông tin của các sinh viên, thông tin gồm: - Mã sinh viên (chuỗi 10 ký tự)

-_ Tên sinh viên (chuỗi 50 ký tự) - Năm sinh (số nguyên)

- Điểm (số thực)

Trang 11

CHƯƠNG 4: KIỂU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

Ví dụ 9.14: (Trích đề thi Olympic Tìn học Sinh viên toàn quốc 2008, khối thi: Cá nhân

Cao đăng)

Vị Giám đốc công ty XYZ cần gửi một văn bản quan trọng tới một đối tác của mình Đề bảo mật văn bản, Giám đốc quyết định mã hóa văn bản trước khi gửi Văn bản là một xâu các chữ cái la tỉnh in thường Giám đốc chia văn bản thành 2 xâu liên tiếp Sb va Se Lan

lượt viết 2 xâu Sb và Se nhưng điều theo thứ tự ngược lại ô ¡ông nhận được xâu mã hóa Q Bức thư thứ nhất gửi cho đối tác có nội đung là Q Để đối tác đọc được văn bản, ông gửi

thêm một bức thư thứ 2 trong đó chứa khóa để giải mã: độ dài k xâu Sb

Ví dụ nội dung bức thư S=”programming” được chia thành 2 đoạn: Sb=”progam”, Se=”ming”

Ta nhận được xâu mã hóa Q=”margorpgnim” với khóa k=7

Yêu cầu : cho xâu mã hóa Q và khóa k, hãy xác định xâu S (k >0 và không vượt quá độ

đài xâu S)

Dữ liệu: Vào từ fñile văn bản LETTER.INP, trong đó dòng đầu chứa xâu mã hóa Q có độ đài từ 1 đến 250, dòng thứ 2 chứa khóa k

Kết quả: Ghi ra file văn bản LETTER.OUT xâu S tìm được LETTER.INP LETTER.OUT margorpgnim programming 7 1 #include <stdio.h> 2 #include <string.h>

3 #define input "LETTER.INP"

Trang 12

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA Ví dụ: IIMAGE INP IIMAGE OUT 3 4 1321 1231 3456 65 4 3 7030 2.503 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h>

#define input "TTMAGE.INP"

#define output "IIMAGE.ouT" int main() FILE* £1, *£2; fl II fopen (input, "r"); £2 = fopen(output, "w"); int a[250] [250]; int n,m;

fscanf (f1,"%d%d", &m, &n);

Trang 13

CHƯƠNG 4: KIỂU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 8 FILE *f£; 9 char *fname=new char; 10 printf("Ten file: "); 11 scanf("%s", fname) ; 12 if((f=fopen(fname, "r")) == NULL) 13 { 14 printf("Loi: Khong the mo file [%s]\n", fname); 15 return 1; 16 } 17 printf("Tap tin %s co $ld ky tu\n", fname, CharCount (f)); 18 fclose(f); 19 getch(); 20 return 0; 21 |}

Kết quả chạy chương trình:

ifen “file: test.txt

flap tin test.txt co 3@ ky tu

Vi du 9.13: Chuong trinh sau cho phép:

Trang 14

CHƯƠNG 4: KIỀU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

9.2.7 Lay vị trí hiện thời của con trỏ file

long ftell(<con tré file>);

//Tra vé vi tri hién tai cta con tré file so voi vi tri dau //file Néu cé 16i, hàm trả về giá trị -1L

Lưu ý: Giá trị hàm trả về sẽ không đúng với file được mở ở chế độ văn bản do các ký tự

carriage-return va linfeed Một ứng dụng thông dụng là để xác định kích thước của file

khi con trỏ năm ở cuỗi file

Ví dụ 9.11: Đọc 100 bytes từ file pArA DAT và cho biết vị trí của con trỏ file 1 FILE *f; 2 long position; 3 char list[100];

4 |fseek(f, OL,SEEK_SET); // Vé dau file

5 fread(list, sizeof(char), 100, £); // Dec ra 100 bytes 6 position = ftell(fp); // Vi tri con tré file

Ví dụ 9.12: Nhập tên một file bất kỳ có trên đĩa và dém số ký tự có trong file đó Nếu

thao tác mở file không thành công, cân xuất thông báo lỗi

Trang 15

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

SEEK_CUR: Vi tri hién thoi cua con tré file (= 1)

SEEK_END: Vi tri cudi file (= 2)

SEEK_SET: Vi tri dau file (= 0)

Ta thường ứng dụng hàm fseek dé :

Đưa con trỏ file về vị trí cuối file: fseek(fp, 01,SEEK_END) ;

Đưa con trỏ file về vị trí đầu file: fseek(fp, 0L,SEEK SET) ;

Vi du 9.10: Vi du 9.5 duge viết lại dùng hàm £seek (), khi đó ta không cần mở file 2 lần mà chỉ cần mở file 1 lần với chế độ “w+” như sau: 1 int main() 2 if 3 FILE *f;

4 char fname[]="DATA DAT";

5 char s[]=“Ly Tu Trong”;

6 int i=0; float x=3.1;

// Ghi giá trị của các biến vào file

7 if((f=fopen(fname, "wt")) == NULL) return 0;

8 fprintf(f, "$s%c", s, '\n');

9 fprintf(f, "Sdce", i, '\n');

10 fprintf(£, "SE", x);

// Đưa con trỏ file về đầu file

11 fseek(fp, OL, SEEK SET);

// Đọc nội dung file ra các biến

12 fscanf(f, "%s", s); printf("s=\"%s\"\n", s);

13 fscanf(f, "$d", &1); printf("i=sd\n", 1);

Trang 16

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 20 scanf ("ss", x.name) ; 21 JÊ (strcmp(x.name,"#") == 0) break; 22 scanf("%d", &x.age); 23 fwrite(&x, sizeof (Person), 1, £); 24 } 25 fclose(f); 26 | } 27 | void DocFile (char fname[]) 28 | { 29 FILE *f; Person x; // Mở file để doc 30 printf("\n\nXuat du lieu tu tap tin ra man hinh:\n\n"); 31 if((f=fopen(fname, "r")) == NULL) 32 { 33 printf("Khong the mo file %s\n", fname); 34 getch(); return ? 35 } // Đọc dữ liệu từ file và in ra màn hình 36 printf("DANH SACH GOM:\n"); 37 printf ("TEN\tTUOI\n");

38 while (fread(&x, sizeof (Person), 1, f)!= 0)

39 printf ("ts\t%d\n", x.name, x.age);

40 fclose(f);

41 |}

9.2.6 Dich chuyén con tré file

Khi mở file, con trỏ file luôn ở vị tri đầu file, trừ trường hợp file được mở để ghi thêm

bang mode "a" hay "at" (append) thi con trỏ file sẽ ở cuối file Hàm £seek () cho

phép dịch chuyển con trỏ file đến vị trí bất kỳ với số byte tương đối so với vị trí trước đó

hay đầu file

int fseek(<Con tré £file>, <Sô byte >, <Vị trí bắt dau>);

<Vi tri bat dau> (origin): sẽ nhận một trong các giá trị sau (định nghĩa trong

header stdio.h):

Trang 17

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 6 return; 7 dem = fread(&s, sizeof(int), 10, f); 8 fclose(f);

9 printf("So phan tu da doc: $d\n", dem); 10 | for(int i=0; i<10; i++)

11 Đrintf("%4d", s[i]);

Ví dụ 9.9:

Các hàm DoeF4 1e () ; GhiFile() ở ví dụ 9.6 được viết lại ding ham freadQ, fwrite() Trong đó thông tin mỗi người được thể hiện bằng một struect có tên Person 1 typedef struct Person 2 |f 3 Char name[10]; 4 int age; 5 [hi 6 void GhiFile(char fname[]) 7 { 8 FILE *f£; Person x;

// M& file d& ghi

9 if((f=fopen(fname, "a")) == NULL) 10 { 11 printf ("Khong the mo file %s\n", fname) ; 12 getch(); 13 return ; 14 }

Trang 18

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

d Hàm đọc ghi đữ liệu £read() và £write ()

fread (<Ðịa chỉ biến>,<Kích thước>,<Số ptử>,<Con trỗ file>);

// Đọc dữ liệu từ file vào biên

⁄⁄ Trả về số phần tử đọc được, ngược lại trả về 0

fwrite (<Địa chỉ biễn>,<Kích thước>,<Sỗ ptữ>,<Con trỏ file>);

⁄⁄ Ghi d& liéu tz bién vao File

// Trả về số phần tử đọc được, ngược lại trả về 0 <Kích thước> (size): Kích thước mỗi phần tử dữ liệu, được tính bằng byte <số ptử> : Số phần tử được đọc/ghi Ví dụ 9.7: Ghi dãy số nguyên 23, 3, -5, 56, 484, 67, 0, 126, 21 vào file có tên INT.DAT 1 FILE *f; 2 char fname[]="INT.DAT"; 3 int s[{10]=(23, 3, 5, 56, 484, 67, 0, 126, 21, 99}; 4 int dem; |

5 if ( (f=fopen (fname, "wb")) == NULL) return;

Trang 19

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 } getch(); return ; } // Đọc đỡ liệu từ file và in ra màn hình Đrintf("DANH SACH GOM:\n"); printf ("TEN\tTUOI\n");

while ((fscanf (f£,"%s%d", name, &age)) != EOF)

printf ("ts\t$d\n", name, age); fclose(f); int main() { } char fname[20]; printf ("Nhap ten file muon luu:");gets (fname) ; GhiFile (fname) ; DocFile (fname) ; getch (); return 0; Két qua chay chuong trinh:

cš C:Macuments and Settings\svVAy Eã xị hap ten file muon luu:C:xNSŨỮ.Cx€ al

Trang 20

CHƯƠNG 4: KIỀU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 1 void GhiFile(char fname[]) 2 |{ 3 FILE *f;char name[50];int age; // Mở file đề ghi 4 if((f=fopen(fname, "“a")) == NULL) 5 { 6 printf("Khong the mo file s\n", fname); 7 getch(); 8 return ; 9 }

// Nhập đữ liệu từ bàn phím và ghi vào file

Trang 21

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA // Ghi giá trị của các biến vào file 8 if((f=fopen(fname, "w")) == NULL) 9 return 0; 10 fprintf(f, "%s%c", s, "\n'); 11 fprintf(f, "dc", i, ‘\n'); 12 fprintf(£, "Sf", x); 13 fclose(f); // Đọc nội dung file ra các biến 14 1£((f=fopen (fname, "r")) == NULL) 15 return 0; 16 fscanf(f, "%s", s); printf("s=\"Ss\"\n", s);

17 Escanf(f, "$d", &1); printf ("i=$d\n", i);

18 fscanf(f, "ti", &x); printf("f=sf\n", x); 19 fclose(f); 20 getch(); 21 return 0; 22 | } Két qua chay chwong trinh:

Vi du 9.6: Chương trình sau cho phép:

- Nhập đữ liệu gồm tên và tuổi của từng người và lưu vào file (tên file do người dung nhập vào) Nếu file chưa có thì tạo mới, nếu đã có thì ghi thêm dữ liệu vào cuối file Khi nhập tên là dấu "#" sẽ kết thúc nhập đữ liệu

- Đọc lại file và xuất danh sách lên màn hình

Trang 22

CHƯƠNG 4: KIỀU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 4 Char s[100];int i, ch; 5 1£((f=fopen("C:\NTEXT.TXT", "rt”)) == NULL) 6 return 0; 7 while(!feof (£)) 8 { 9 ch = fgetc(f); // fgets(s, 100,f); 10 printf (“%c”,ch); // printf (“%s",s); 11 } 12 £close (£) ; 13 getch(); 14 return 0; 15 | } c.Ham doc, ghidirligu fscanf() va fprintf ()

int f£scanf(<Con tré file>,<Chuéi dinh dang>,<Dia chi cdc bién>);

⁄⁄ cho phép: đọc đữ liệu từ file và lưu vào các biễn Nếu thành công trả về số phần tử đọc ghi được, ngược lại trả về EOF

int fprintf (<Con trỏ £ile>,<Chuỗi định đạng>,<Danh sách biến>)

⁄⁄ ghi dữ liệu từ các biên bên ngoàii vào file Nếu thành công

Trang 23

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 3 char s[]="1Ly Tu Trong”; 4 FILE *f; 5 if ((f=fopen("C:\\TEXT.TXT", "wt")) != NULL) 6 { 7 fputs(s, £); 8 fputc('\n', £); 9 fputs("2011", £); 10 fclose(f); 11 printf("Ghi thanh cong!"); 12 } 13 else printf("Loi mo file"); 14 getch(); 15 return 0; 16 |} }

N6i dung file C\TEXT.TXT duoc tao :

ex C:Wocuments and Settings PEE i { | i b Cac ham doc ky tu va chudi tir file: fgetc() va fgets ()

int fgetc(<con tré file>); //Trad vé mé ASCII cia ky tw doc dugc, //néu không đọc được trả về EOF

| char* fgets (<bién chuéi>,<sé ky ty téi da>,<con tré file>);

Trang 24

CHUONG 4: KIEU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 3 if(£ != NULL) 4 { 5 printf£("Mo file thanh cong"); 6 //Các xử lý trên file 7 fclose(f); 8 } 9 else printf("Mo file khong thanh cong");

9.2.4 Kiểm tra cuối file:

Khi đọc dữ liệu từ file, để tránh lỗi xảy ra khi con trỏ file đã trỏ vào vị trí cuối file, ta

dùng hàm feof ()

int feof(<con tré file>); //tra vé sé nguyén ¥ 0 néu con tre // file ở cuỗi file, ngược lại trả về 0 Hàm feofQ có thể được sử sụng như sau: whi le (!£eo£ (£p) ) { <Thao tác đọc file>

9.2.5 Đọc và ghi đữ liệu vào file:

a Hàm ghi ký tự và chuỗi vào file: fputc () và fputs ()

int £putc (<Ký tự>, <Con trỏ file>);

int fputs(<Chuéi>, <Con tré file>);

⁄⁄ Trả về một số nguyên không âm nếu việc ghi thành công, ngược ⁄⁄ lại trả về hằng EOF

Vi dy 9.3: Chương trình sau cho phép ghi 2 dòng vào file Texr xT, một dòng là gia trị

Trang 25

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

t: Mở file theo kiểu văn bản Trong dé CTRL+Z dugc xem là ký tự kết thúc file

EOF khi ghi dữ liệu vào file

b: Mởfile theo kiểu nhị phân

Vi dy 9.1: Mở file "E:\VANBAN.TXT" để ghi 1 FILE *£; 2 f=fopen (”E: \\VANBAN.,TXT", "ự") 3 if(f!= NULL) 4 { 5 printf£("Mo file thanh cong"); 6 7 } 8 else 9 printf("Mo file khong thanh cong"); 9.2.3 Dong file

Sau khi thực hiện xong các tác vụ trên file, ta cần phải thực hiện thao tác đóng file Thao

tác này có tác dụng ghi toàn bộ các dữ liệu đang nằm trong các bộ nhớ đệm (temporary file buffer) dành cho file lên đĩa, giải phóng vùng nhớ cho bộ đệm, tránh việc mất mát hay hỏng dữ liệu trên file

Để đóng 1 file ta dùng hàm £elose () , để đóng các file hiện đang mở, ta dùng hàm

fcloseall ()

int fclose(<Con tré file>); // Néu thanh céng tra vé tri 0, ⁄⁄ ngược lại trả về trị EOF (=-1)

Trang 26

CHƯƠNG 4: KIỄU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

9.2 CÁC THAO TÁC TRÊN FILE

Để đọc/ghi file trong C/C++,.có 2 phương pháp: xử lý nhập/xuất cấp thấp (low level)

và xử lý nhập/xuât cap cao (high level) Ưu điểm của xử lý nhap/xuat cap cao là không

phụ thuộc vào hệ điều hành và có nhiều hàm dùng cho nó hơn là xử lý nhập/xuất cập

thập

9.2.1 Khai báo con tré file

Khi muốn xử lý nhập/xuất một file , ta can sit dung một con trỏ file (file pointer) cho

nó Con trỏ file là con trỏ có kiểu cấu trúc E ILE, trỏ đến từng byte trên file , hay nói cách khác nó chứa địa chỉ của từng mẫu tin trong file

Cách khai báo con trỏ file như sau: | FILE *<Con tré file>; | Chẳng hạn khai báo con trỏ file có tên £ : FILE *f; 9.2.2 Mở file

Trước khi đọc/ghi đữ liệu trong file , ta phải thực hiện thao tác mở file

FILE * fopen(<Tén file>, <Kiéu Tnở>) ;

//Nễu mỏ không thành công trả về NULI

<Tén file> Tên file muốn mở

<Kiễu mở> Kiểu mở file (mode), được xác định như sau:

"x": MG file dé doc

"w": Mo file file dé ghi Nếu file đã tồn tại, nội dung trước đó sẽ bị xóa

"a"; Mở file để ghi vào cuối file (append) mà ta không cần phải thực hiện thao tác chuyên con trỏ file đến vị trí kết thúc file (EOF - End Of File marker) Nếu

file không tôn tại, file mới sẽ được tạo

"+" : Mở file đề đọc và ghi, file muốn mở phải tôn tại

"w+" :; Mở một file rỗng cho thao tác đọc và ghi Nếu file đã tồn tại, nội dung có trước đó sẽ bị xóa

"at": Mo file cho thao tác đọc và ghi vào cuối (append) Trước khi thực hiện ghi dữ

liệu, con trỏ sẽ được tự động chuyền đến vị trí dấu EOEF File sé được tạo mới

nêu khơng tơn tại

Ngồii ra, ta có thể viết thêm vào tùy chọn t hoặc b vào chuỗi mode để xác

định file được xử lý theo kiểu văn bán (text) hay nhi phan (binary):

Trang 27

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

§9 TAP TIN (FILE) 9.1 KHAI NIEM

Tập tín (file) là tập hợp dữ liệu dưới dang các byte được lưu trữ trên thiết bị lưu trữ

như đĩa cứng (hard disk) , dĩa mềm (floppy disk), CD, DVD, USB Memory Stick, va

được gan cho một tên theo qui ước của hệ điều hành Các file được tạo bởi các chương

trình và chúng được dùng để chứa dữ liệu vào (input) hay dữ liệu xuất (output) của một hay nhiều chương trình

Một cách tông quát về mặt cấu trúc, file là một tập các mẫu tin (record), mỗi mẫu tin là

một tập các byte Thực chất file là một dòng (stream) các byte được bế trí liên tục, việc

đọc/ghi dữ liệu từ/vào file là thao tác trích (extract) hay chén (insert) đữ liệu vào/ra khỏi stream

Xét vé mat truy cập tới các mẫu tin hay phan tir trong file, ta chia chúng ra làm 2 lọai: - File truy cập tuần tự (sequential access files): Với thao tác đọc (read), dé đọc một

mẫu tin thứ ¡, ta cân duyệt qua tât cả các mẫu tin trước đó bắt đầu từ mẫu tin đầu

tiên Với thao tác ghi (write), mẫu tin mới sẽ được thêm vào vị trí cuối file

- File truy cập ngẫu nhiên (random access file): Với thao tác đọc (read), ta có thể đọc

mẫu tin nằm tại vị trí bất kỳ nào đó trong file mà không cần phải duyệt qua các mẫu

tin trước đó, điều này được thực hiện thông qua chỉ mục (ndex) Với thao tác ghi

(write) cũng tương tự như vậy, ta có thể chèn một mẫu tin mới vào vị trí bất kỳ

trong file thông qua chỉ mục

Xét về mặt lưu trữ, có 2 lọai file:

- File văn bản (text file): Mỗi mẫu tin là 1 byte và chúng là các ký tự ASCII, các dòng

được phân cách nhau thông qua ký tự "new line" (Mr, có trị hex là 0x0D0A)

- File nhị phân (binary file): Mỗi mẫu tin có nhiều byte, chẳng hạn với kiểu int thì

mỗi mẫu tin sẽ là 2 byte hay 4 byte (tùy theo bộ vi xử lý 16 bits hay 32 bits và trình biên dịch)

Các thao tác để xử lý dữ liệu trên file được thực hiện thông qua các hàm xuất/nhập file

được định nghĩa sẵn trong file header stdio.h

Tuy nhiên cần lưu ý các bước chính trong một quá trình xử lý file và các hàm liên quan gom:

| M6 file > Xử lý dữ liệu trong file -> Đóng file

- Mở file: fopen () , freopen ()

- Xử lý dữ liệu: fseanf(), £printf() , fread(), fwrite(), £fgetc(),

fgets(), fputc(), fputs(), fseek{), feof ()

- Dong file: fclose(), feloseall ()

Trang 28

CHUONG 4: KIEU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA struct tm {

tm sec Seconds after minute (0 - 59) tm min Minutes after hour (0 — 59)

tm_hour Hours after midnight (0 - 23) tm_mday Day of month (1 - 31)

tm mon Month (0 — 11; January = 0)

tm_year Year (current year minus 1900)

tm_wday Day of week (0 ~ 6; Sunday = 0)

tm_yday Day of year (0 — 365; January 1 = 0) };

Để lấy ngày hiện thời, hàm 1ocaltime (&timer) được gọi, trong đó tham số timer là con trỏ trỏ đến kiểu time t đã được định nghĩa sẵn Hàm localtime () trả về một con trỏ trỏ vào một struet tm,

Trang 29

CHƯƠNG 4: KIỄU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 15 now = localtime (&timer) ; 16 today.day = now->tm_mday; 17 today.month = now->tm mon+1; 18 today.year = now->tm_year+1900;

19 printf ("Ngay sinh cua ban (dd mm VVVy): ");

20 scanf ("td%d%d", sdob.day, édob.month, &dob.year); 21 if (today.month>dob.month | |

(today.month==dob.month && today.day>=dob day) )

22 age = today.year ~ dob.year;

23 else

24 age = today.year ~- dob.year - 1;

25 printf ("\n\nKet qua:\n");

26 printf ("Ngay sinh cua ban: $d/%d/%d\n", dob.day, dob.month, dob year); 27 printf("Hom nay la ngay : %d/%d/%d\n", today day, today.month, today.year); 28 printf("Tuoi cua ban la : $d", age); 29 getch(); 30 return 0; 31 | }

Két qua chay chuong trinh:

gay sinh cua ban: 18/5/1981

fiom nay la ngay : 29/11/2085

: uoi cua ban la : 24

Trong chương trinh ta str dung cau tric struct tm được xây dựng sẵn trong file header time.h như sau:

Trang 30

CHUONG 4: KIEU DU LIEU DO NGUO! DUNG ĐỊNH NGHĨA oa Ten: Phan Khang am sinh : 1992 o Ten: Phan Thi fn jam sinh = 1991 Ten: Nguyen Kin am sinh : 1992 Ma So Ho ten

THOL Phan Khang

THO2 Phan Thi An TH83 Nguyen Ki Vi du 8.7:

Trang 31

CHƯƠNG 4: KIỀU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 } printf("Ma SV: "); £flush (stdin); gets (a[1].ms) ; Đrintf("Ho Ten: "); fflush(stdin); gets(a[i].ten);

printf£("Nam sinh : "); scanf("%d", ga[il.ns); void Output (SV a[],int n)

{

}

printf("\n\nDanh sach sinh vien:\n");

printf ("STT\tMa So\tHo ten\t\tNam sinh\n"); printf (”T~ -~~~~~~~~~~~~~~~~~—~—~~~~—~~~—~ \n");

for(int i=0; i<n; itt)

printf ("sd\t%s\t%s\téd\n", i+1, a[i].ms, a[i].ten, a[i].ns); int main() { SV a[N];int n; Input (a,n); Output (a,n); getch(); return 0;

Kết quả chạy chương trình:

Trang 32

CHUONG 4: KIEU DU LIEU DO NGUO! DUNG ĐỊNH NGHĨA Ví dụ 8.5: 1 5V x,*p,a[100]; 2 x.ms=1; 3 strcpy(x.ten , "Phan Khang"); 4 std1.ns=1992; 5 p=(SV*) malloc(sizeof (SV)); 6 p->ms=2; 7 strcpy(p->ten , "Phan Thi An"); 8 p->ns=1991; 9 a[0] ms=3; 10 | strepy(a[0].ten , "Nguyen Kim"); 11 |a[0].ns=1992;

Ví dụ 8.6: Chương trình sau cho phép nhập vào một danh sách sinh viên gồm các thông

tin: mã sinh viên, họ tên , năm sinh Sau đó in danh sách sinh viên theo dang bang 1 #define N 100 2 typedef struct SV 3 { 4 char ms[10]; 5 char ten[50]; 6 int ns; 7 }¿ 8 void Input(SV a[],int &n) 9 {

Trang 33

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

8.1.3 Định nghĩa kiểu dữ liệu mới bằng typedef

Ngoài cách khai báo cấu trúc dữ liệu như trên, ta cũng có thể định nghia struct ding

tir khéa typedef

Khi ding typedef ngoài việc định nghĩa một kiểu dữ liệu mới, việc khai báo các biên sẽ không phải viết từ khóa stxuet nữa nên sẽ tự nhiên hơn, như các kiểu đữ liệu cơ sở khác typedef struct <Tên kiểu> { <Mô tả các thành phẩn>; }; Vi du 8.4: 1 typedef struct SV 2 { 3 int ms; 4 char ten[50]; 5 int ns; 6 |}; //Khai báo biến kiểu SV: 7 SV t; 8 SV *p; 9 SV a[100];

8.2 THAM KHAO CAC THANH PHAN CUA STRUCT

Khi các biến struet đã được khai báo, ta có thể truy cập đến từng thành phan/thanh vién (component/member) cia struct băng toán tử thành phần (member operator) với dâu châm "." đối với biến thường hoặc dùng dẫu mũi tên "—»" khi dùng biên con trỏ

<Tên bién>.<Thanh phan>; //Bién thường

<Tén bién> -> <Thanh phan>; // Bién con tré

Giáo trình môn Kỹ thuật lập trình 91

Trang 34

CHƯƠNG 4: KIỀU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA 1 struct SV 2 { 3 int ms; 4 char ten[50]; 5 int ns; 6 } x, yi 7 struct SV t; 8 struct SV *p; 9 struct SV SinhVien[100]; Ví dụ 8.2: Mô tả struct có tên date để chứa ngày tháng năm 1 struct date 2 { 3 int day; 4 int month; 5 int year; 6 |};

7 struct date today;

8 struct date birthday[100]; 8.1.2 Khai báo và khởi tạo giá trị cho biến struct struct <Tén kiéu> <Tén bién> = ({<Giá tri cia cdc thanh phan>}; Ví dụ 8.3:

1 struct SV x={1, "Phan Khang", 1992};

2 struct SV SinhVien[]={{1,"Phan Khang",1992},

Trang 35

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA SinhVien[1] SinhVien[0] SinhVien[2] ĐinhVien[3] int ba = ¬———- Đ char + | unsigned int

Hình 4.1: Minh họa một mảng các struct

8.1 KHAI BAO CAU TRÚC DỮ LIỆU

8.1.1 Khai báo struct

Cũng như các biến thông thường, để có thể sử dụng một kiểu đữ liệu mới dùng struct,

ta cần khai báo và mô tả một struct theo cú pháp sau: struct [<Tén kiéu>] { <Mõ tả các thành phẩn>; } [<Danh sách biến>];

<Tén kiéu> Tên của kiểu đữ liệu mới, tên này không được trùng

với kiểu đữ liệu đã có

<Danh sách biến> Danh sách các tên biến có kiểu struct đã mô tả, phân

cách băng dau “,”

<Mô tả các thành phần> Các mô tả cho từng thành phần trong struct

Sau khi một struet đã được mô tả như cú pháp ở trên, ta có thể khai báo các biến có

kiêu đữ liệu mới này theo cách khai báo biến theo cú pháp

| struct <Tén kiéu> <Danh sach bién>;

Vi du 8.1:

M6 ta struct cé tên SV gôm mã sô, họ tên, năm sinh và khai báo 2 biến x và y có kiêu

dữ liệu mới này:

Trang 36

CHƯƠNG 4: KIÊU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

- CHƯƠNG 4

KIỂU DỮ LIỆU DO NGƯỜI DÙNG ĐỊNH NGHĨA

TÓM TẮT NỘI DUNG:

- _ Kiểu dữ liệu có cấu trúc (struct), cách khai báo, tham khảo các thành phần của biến kiêu struct Các thao tác trên mang struct

- Kiéu file, các thao tác trên file

_ MỤC TIỂU: Sau khi học xong sinh viên thực hiện được

-_ Các thao tác trên biến, mảng có kiểu struct gồm:

© Khai báo biến, mảng kiểu struct

e© Xuất mảng struct theo dạng bảng

e© Xuất, đếm, tính toán , cập nhật theo điều kiện cho trước trên mảng struct

e_ Tìm phần tử lớn nhất nhỏ nhất trên một thành phần của mang struct

- Cac thao tac trên file gồm:

® Mở, đóng file, dịch chuyên con trỏ file

® Đọc, ghi file ding cdc ham fputs(), fputcQ, fzetsQ, fgetc(Q), fscanfQ, fprintfQ,

treadQ, fwriteQ

§8 KIỂU CẤU TRÚC (STRUCT)

Struct (structure) 14 m6t dạng thức mà C/C++ cung cấp cho lập trình viên khả năng

xây dựng một kiêu dữ liệu mới trên cơ sở các kiểu đã được định nghĩa và kết hợp chúng lại với nhau

Chẳng hạn để lưu thông tin của một sinh viên gồm mã số, họ tên, năm sinh, thường thì ta cần 3 biến có kiểu khác nhau Nếu muốn lưu một danh sách sinh viên với các thông tin như trên, ta có thể xây dựng 3 mảng 1 chiều Tuy nhiên, lúc đó sẽ không có sự đồng bộ khi tham khảo đến 1 sinh viên trong danh sách, việc xử lý cũng sẽ trở nên phức tạp hơn

Với cách tiếp cận khác, dùng struet, sẽ làm cho bài tóa trên trở nên đơn giản Lúc đó, mỗi một sinh viên là một cấu trúc với 3 thông tin ràng buộc nhau: MS - Mã số, TEN

- Họ tên, NS — Năm sinh Danh sách sinh viên sẽ là một mảng các cấu trúc đã nêu, được

mô tả như hình vẽ Trong đó, các thành phần (components) hay thành viên (members)

của một struet có kiểu dữ liệu cơ sở, chẳng hạn 1D có kiểu int, TEN có kiểu chuỗi

char*, và NS có kiểu unsigned int Trong những cấu trúc phức tạp khác thì kiểu dữ

liệu của thành phần cũng có thê lại là một struct hay kiéu ditt liệu khác do người dùng

định nghĩa

Trang 37

CHƯƠNG 3: CON TRO

Xuất: "83 111 110","78 97 109","84 117 97 110"

3.5

Viết chương trình dùng con trỏ cho phép người dùng nhập vào danh sách các sinh viên

gồm họ tên, năm sinh, điểm sau đó thực hiện các thao tác: a In ra toàn bộ danh sách đã nhập theo dạng bảng như sau:

SIT Hovaten Namsinh Diem

1 Tran Van Tuan 1992 7

2 Nguyễn ThiLan 1993 8

A oA * tA , ok +

c Đêm xem có bao nhiêu sinh viên có điểm nhỏ hơn 5

Trang 38

CHƯƠNG 3: CON TRỎ BÀI TẬP CHƯƠNG 3 3.1 Viết chương trình dùng con trỏ thực hiện các chức năng sau (mỗi chức năng viết một hàm riêng):

a Dùng phương pháp cấp phát bộ nhớ động để nhập một dãy gồm n số nguyên In ra màn hình:

b Todan bộ day số theo thứ tự đã nhập

c Tòan bộ dãy số theo thứ tự ngược với thứ tự đã nhập d Day con gồm các số tại các vị trí chỉ mục chẵn

e Dãy con gồm cac sé chin

rh Đêm xem có bao nhiéu sé chan a £ A š + ~ A Tính tông các số chấn của dãy số pm ae Tìm số lớn nhất trong dãy số Tìm số âm lớn nhất trong dãy số me j Xóa tất cả cdc sé chin k Chén một số x vào vị trí k trong day số 3.2 Viết chương trình dùng con trỏ nhập vào một ma trận vuông cấp n>2 Thực hiện: — Inma trận ra màn hình

— Đếm số các phân tử có giá trị lẻ và tính tổng của chúng

— _ Tìm phân tử lớn nhất của từng dòng và nhỏ nhất của từng cột

3.3

Viết chương trình dùng con trỏ nhập vào một danh sách nhiều họ tên sinh viên Nhập vào một họ tên, tìm và cho biết có sinh viên nào trong danh sách trùng với họ tên đã nhập hay không Yêu câu dùng các hàm riêng cho từng chức năng

3.4

Viết chương trình dùng con trỏ nhập vào một danh sách có nhiều tên sinh viên Thay vì in các ký tự trong các chuỗi, in ra màn hình mã ASCII tương ứng với từng ký tự

Vi du:

Nhập: "Son", "Nam", "Tuan"

Trang 39

CHUONG 3: CON TRO 18 return 0; 19 |}

Kết quả chạy chương trình:

ong so sinh vien:

en SU thu 1: Le Hang Ten SU thu 2: Do Nam

“Ho Ten thu 3z Tran Tan

“Ho Ten thu 4: Ho Lan

Trang 40

CHƯƠNG 3: CON TRO

Tương tự dé khai báo một con trỏ 2 cấp hay còn gọi là con trỏ kép dùng để trỏ đến

chuỗi ký tự, ta viết ** trước tên biến

char **list;

Ta có thể xin cấp phát bộ nhớ cho con trỏ list như sau với n là số dòng:

liat = (char**) malloc (n*sizeof (char) ) ;

// list = new char* [n];

Việc tiếp theo là xin cấp phát cho mỗi chuỗi tên Vì mỗi địa chỉ của list bồm

(1ist+0) , (1ist+1) ;- (List+2) , trỏ vào một chuỗi, do đó để xin cấp phát vùng nhớ

cho n chuỗi ta dùng cấu trúc lặp với n lần lặp: for(int i=0; i<n; i++)

list[i] = (char*) malloc (m*sizeof (char) ) ;

// list[i] = new char [m] ;

với m là độ đài của chuỗi muốn xin cấp phát

Sau đây là toàn bộ chương trình:

1 int main(void)

2 {

3 char **list; int n;

4 printf("Tong so sinh vien: ")? scanf("Sd", &n);

5 if(n>0) list=(char**)malloc(n*sizeof (char) ); 6 elsereturn 0; 7 for(int i=0; i<n; i++) 8 { 9 list [i]=(char*)malloc(50*sizeof (char) ); 10 printf("Ho Ten SV #$d: ", 1+1); 11 fflush (stdin); 12 gets(list[i]); 13 }

14 printf("\nDanh sach sinh vien:\n");

15 for(int i=0; i<n; itt)

16 print£("Sd %s\n",i+1, *(listt+i)); 17 getch();

Ngày đăng: 06/08/2022, 16:10

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w