Phương pháp lập trình - Phần: Kiểu con trỏ

pdf 42 trang vanle 2620
Bạn đang xem 20 trang mẫu của tài liệu "Phương pháp lập trình - Phần: Kiểu con trỏ", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfphuong_phap_lap_trinh_phan_kieu_con_tro.pdf

Nội dung text: Phương pháp lập trình - Phần: Kiểu con trỏ

  1. TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP THÀNH PHỐ HỒ CHÍ MINH Phương pháp lập trình Tập tin TS. Ngô Hữu Dũng
  2. 1. GiỚI THIỆU  C/C++ hỗ trợ 2 hệ thống nhập xuất:  Một hệ thống thừa kế từ ngôn ngữ C  Một hệ thống nhập xuất hướng đối tượng của C++. Phương pháp lập trình - Tập tin
  3. 2. Streams và Files  Hệ thống nhập xuất của C  Cung cấp một giao diện (interface) nhất quán độc lập với thiết bị thật sự mà chương trình tương tác.  cung cấp một mức độ trừu tượng giữa lập trình viên và thiết bị nhập xuất. Sự trừu tượng này được gọi là stream và thiết bị thật sự được gọi là file. Phương pháp lập trình - Tập tin
  4. 3. Streams (dòng nhập xuất)  Hệ thống file của C được thiết kế để làm việc với nhiều loại thiết bị khác nhau như terminals (thiết bị đầu cuối), các loại ổ đĩa, băng từ,  Hệ thống file chuyển đổi mỗi loại thành một thiết bị logic gọi là stream. Tất cả stream có cùng hành vi Phương pháp lập trình - Tập tin
  5. 3. Streams (dòng nhập xuất)  Stream độc lập với thiết bị nên cùng một hoạt động trên stream như ghi vào một tập tin trên đĩa cũng có thể dùng để ghi vào loại thiết bị khác như console (màn hình).  Có hai loại stream:  Văn bản (text)  Nhị phân (binary). Phương pháp lập trình - Tập tin
  6. 3.1. Text Streams  Một text stream là một chuổi các ký tự. Trong một text stream, một số ký tự có thể bị chuyển đổi tùy thuộc môi trường.  Ví dụ, ký tự newline ('\n') có thể bị đổi thành cặp ký tự carriage return/linefeed (ký tự xuống dòng và về đầu dòng). Phương pháp lập trình - Tập tin
  7. 3.1. Text Streams  Không có quan hệ một-một giữa các ký tự được viết (hay đọc) và những ký tự trên các thiết bị ngoài. Do đó số ký tự được viết (hay đọc) có thể khác số số ký tự trên thiết bị ngoài. Phương pháp lập trình - Tập tin
  8. 3.2. Binary Streams  Một binary stream là một chuỗi bytes tương ứng một-một với chuổi bytes trên thiết bị ngoài. Nghĩa là không có sự chuyển đổi xảy ra. Do đó, số bytes được viết (hay đọc) thì bằng với số bytes trên thiết bị ngoài. Phương pháp lập trình - Tập tin
  9. 4. FILES  Một file có thể là một tập tin trên đĩa, một terminal, hay máy in.  Để tạo kết nối (associate) giữa một stream với một file ta dùng hoạt động mở (open).  Khi file được mở, thông tin có thể được trao đổi giữa file và chương trình. Phương pháp lập trình - Tập tin
  10. 4. FILES  Không phải tất cả file đều có cùng khả năng như nhau.  Ví dụ, một tập tin trên đĩa (file) có thể hỗ trợ truy xuất ngẫu nhiên trong khi đó máy in (cũng là file) thì không thể.  “Tất cả stream là như nhau nhưng file thì không". Phương pháp lập trình - Tập tin
  11. 4. FILES  Để ngắt kết nối giữa một stream với một file ta dùng hoạt động đóng (close). Nếu đóng một file đang mở cho xuất (output) thì nội dung của stream tương ứng được viết ra thiết bị ngoài.  Qúa trình này được gọi là flushing và đảm bảo là không có thông tin bị để lại trong vùng đệm (buffer). Phương pháp lập trình - Tập tin
  12. 4. FILES  Tất cả file được tự động đóng khi chương trình mở chúng kết thúc bình thường. Files không được đóng khi chương trình mở chúng bị kết thúc bất thường như bị treo (halt) hay khi chương trình thực hiện hàm abort().  Mỗi stream liên đới với một file có một cấu trúc kiểu FILE. Phương pháp lập trình - Tập tin
  13. Con Trỏ FILE . Một con trỏ tập tin phải cần cho việc đọc và ghi các tập tin .Nó là một con trỏ đến một cấu trúc chứa thông tin về tập tin. Thông tin bao gồm tên tập tin, vị trí hiện tại của tập tin, liệu tập tin có đang được đọc hay ghi, và liệu có bất kỳ lỗi nào xuất hiện hay đã đến cuối tập tin . Định nghĩa lấy từ stdio.h bao gồm một khai báo cấu trúc tên FILE . Câu lệnh khai báo duy nhất cần thiết cho một con trỏ tập tin là: FILE *fp Phương pháp lập trình - Tập tin
  14. Các Hàm Cơ Bản Về FILE Tên Chức năng fopen() Mở một tập tin fclose() Đóng một tập tin fputc() Ghi một ký tự vào một tập tin fgetc() Đọc một ký tự từ một tập tin fread() Đọc từ một tập tin vào một vùng đệm fwrite() Ghi từ một vùng đệm vào tập tin fseek() tìm một vị trí nào đó trong tập tin fprintf() Hoạt động giống như printf(), nhưng trên một tập tin fscanf() Hoạt động giống như scanf(), nhưng trên một tập tin feof() Trả về true nếu đã đến cuối tập tin ferror() Trả về true nếu xảy ra một lỗi rewind() Đặt lại con trỏ định vị trí bên trong tập tin về đầu tập tin remove() Xóa một tập tin fflush() Ghi dữ liệu từ một vùng đệm bên trong vào một tập tin xác định Phương pháp lập trình - Tập tin
  15. Mở Một FILE Văn Bản . Hàm fopen() mở một stream để sử dụng và liên kết một tập tin với stream đó . Hàm fopen() trả về con trỏ kết hợp với tập tin . Nguyên mẫu của hàm fopen() là: FILE *fopen(const char *filename, const char *mode); Chế độ Ý nghĩa R Mở một tập tin văn bản để đọc w Tạo một tập tin văn bản để ghi a Nối vào một tập tin văn bản r+ Mở một tập tin văn bản để đọc/ghi w+ Tạo một tập tin văn bản để đọc/ghi a+f Nối hoặc tạo mộtPhươngtập pháptin lập trìnhvăn - Tậpbản tin để đọc/ghi
  16.  Ví dụ: FILE *fp; if((fp = fopen("test.txt","w")) == NULL) { cout << "Cannot open file"; exit(1); } Phương pháp lập trình - Tập tin
  17. Đóng Một FILE Văn Bản . Việc đóng một tập tin sau khi sử dụng là một điều quan trọng . Thao tác này sẽ giải phóng tài nguyên và làm giảm nguy cơ vượt quá giới hạn số tập tin có thể mở. . Đóng một stream sẽ làm sạch và chép vùng đệm kết hợp của nó ra ngoài, một thao tác quan trọng để tránh mất dữ liệu khi ghi ra đĩa . Hàm fclose() đóng một stream đã được mở bằng hàm fopen() . Nguyên mẫu của hàm fclose() là : int fclose(FILE *fp); . Hàm fcloseall() đóng tất cả các streams đang mở Phương pháp lập trình - Tập tin
  18. Ghi Một Ký Tự – FILE Văn Bản . Streams có thể được ghi vào tập tin theo cách từng ký tự một hoặc theo từng chuỗi . Hàm fputc() được sử dụng để ghi các ký tự vào tập tin đã được mở trước đó bằng hàm fopen(). . Nguyên mẫu của hàm này là: int fputc(int ch, FILE *fp); Phương pháp lập trình - Tập tin
  19. VD: đọc ký tự từ bàn phím và ghi vào file đến khi gặp kt $ void main() { FILE *fp; char ch; if((fp=fopen(“test.txt”, "w"))==NULL) { cout << "Cannot open file.\n"; exit(1); } do { ch = getchar();//đọc từ bàn phím putc(ch, fp);//ghi vào file }while (ch != '$'); fclose(fp);//đóng file } Phương pháp lập trình - Tập tin
  20. Đọc Một Ký Tự – FILE Văn Bản .Hàm fgetc() được dùng để đọc các ký tự từ một tập tin đã được mở bằng hàm fopen() ở chế độ đọc .Nguyên mẫu của hàm là: int fgetc(int ch, FILE *fp); .Hàm fgetc() trả về ký tự kế tiếp của vị trí hiện hành trong stream input, và tăng con trỏ định vị trí bên trong tập tin lên Phương pháp lập trình - Tập tin
  21. void main() { FILE *fp; char ch; if((fp=fopen(”test.txt”, "r"))==NULL) { cout << "Cannot open file.\n"; exit(1); } ch = getc(fp); // đọc một ký tự while (ch!=EOF) { putchar(ch); // in ra màn hình ch = getc(fp); }fclose(fp); } Phương pháp lập trình - Tập tin
  22. Nhập Xuất Chuỗi . Các hàm fputs() and fgets() ghi vào và đọc ra các chuỗi ký tự từ tập tin trên đĩa . Hàm fputs() viết toàn bộ chuỗi vào stream đã định . Hàm fgets() đọc một chuỗi từ stream đã cho cho đến khi đọc được một ký tự sang dòng mới hoặc sau khi đã đọc được length-1 ký tự. . Nguyên mẫu của các hàm này là: int fputs(const char *str, FILE *fp); char *fgets( char *str, int length, FILE *fp); Phương pháp lập trình - Tập tin
  23. void main(void) { char str[80]; FILE *fp; if((fp = fopen("teststr.txt", "w"))==NULL) { cout << "Cannot open file.\n"; exit(1); } Do { cout << "Enter a string (CR to quit):\n"; gets(str); strcat(str, "\n"); /* add a newline */ fputs(str, fp); } while(*str!='\n'); } Phương pháp lập trình - Tập tin
  24. Mở Một FILE Nhị Phân . Hàm fopen() mở một stream để sử dụng và liên kết một tập tin với stream đó. . Hàm fopen() trả về một con trỏ tập tin kết hợp với tập tin. . Nguyên mẫu của hàm fopen() là: FILE *fopen(const char *filename,const char *mode); Chế độ Ý nghĩa rb Mở một tập tin nhị phân để đọc wb Tạo một tập tin nhị phân để ghi ab Nối vào một tập tin nhị phân r+b Mở một tập tin nhị phân để đọc/ghi w+b Tạo một tập tin nhị phân để đọc/ghi a+b Nối vào một tậpPhươngtin phápnhị lập trìnhphân - Tập tinđể đọc/ghi
  25. Đóng FILE Nhị Phân . Hàm fclose() đóng một stream đã được mở bằng hàm fopen() . Nguyên mẫu của hàm fclose() là: int fclose(FILE *fp); Phương pháp lập trình - Tập tin
  26. Hàm fread() và fwrite() .Hàm fread() và fwrite() là các hàm đọc hoặc ghi dữ liệu không định dạng. .Chúng được dùng để đọc ra và viết vào tập tin toàn bộ khối dữ liệu. .Hầu hết các chương trình ứng dụng hữu ích đều đọc và ghi các kiểu dữ liệu do người dùng định nghĩa, đặc biệt là các cấu trúc. .Nguyên mẫu của các hàm này là: size_t fread(void *buffer, size_t num_bytes, size_t count, FILE *fp); size_t fwrite(const void *buffer, size_t num_bytes, size_t Phươngcount, pháp lập FILE trình - Tập tin *fp);
  27. Sử Dụng feof() .Hàm feof() trả về true nếu đã đến cuối tập tin, nếu không nó trả về false (0). .Hàm này được dùng trong khi đọc dữ liệu nhị phân. .Nguyên mẫu là: int feof (FILE *fp); Phương pháp lập trình - Tập tin
  28. Hàm rewind() . Hàm rewind() đặt lại con trỏ định vị trí bên trong tập tin về đầu tập tin . Nó lấy con trỏ tập tin làm đối số . Cú pháp: rewind(fp ); Phương pháp lập trình - Tập tin
  29. Hàm ferror() . Hàm ferror() xác định liệu một thao tác trên tập tin có sinh ra lỗi hay không . Vì mỗi thao tác đặt lại tình trạng lỗi, hàm ferror() phải được gọi ngay sau mỗi thao tác; nếu không, lỗi sẽ bị mất . Nguyên mẫu của hàm là: int ferror(FILE *fp); Phương pháp lập trình - Tập tin
  30. Xóa Tập Tin . Hàm remove() xóa một tập tin đã cho . Nguyên mẫu của hàm là: int remove(char *filename); Phương pháp lập trình - Tập tin
  31. Làm Sạch các stream .Hàm fflush() sẽ làm sạch vùng đệm và chép những gì có trong vùng đệm ra ngoài tùy theo kiểu tập tin .Một tập tin được mở để đọc sẽ có vùng đệm nhập liệu trống, trong khi một tập tin được mở để ghi thì vùng đệm xuất của nó sẽ được ghi vào tập tin .Nguyên mẫu của hàm là: int fflush(FILE *fp); .Hàm fflush(), không có đối số, sẽ làm sạch tất cả các tập tin đang mở đểPhươngxuất pháp lập trình - Tập tin
  32. Các Stream Chuẩn Mỗi khi một chương trình C bắt đầu thực thi dưới DOS, hệ điều hành sẽ tự động mở 5 stream đặc biệt: • Nhập chuẩn (stdin) • Xuất chuẩn (stdout) • Lỗi chuẩn (stderr) • Máy in chuẩn (stdprn) • Thiết bị phụ trợ chuẩn (stdaux) Phương pháp lập trình - Tập tin
  33. Con Trỏ Kích Hoạt Hiện Hành . Một con trỏ được duy trì trong cấu trúc FILE để lần theo vị trí nơi mà các thao tác nhập/xuất đang diễn ra . Mỗi khi một ký tự được đọc từ hay ghi vào một stream, con trỏ kích hoạt hiện hành (gọi là curp) được tăng lên . Vị trí hiện hành của con trỏ này có thể được tìm thấy bằng sự trợ giúp của hàm ftell(). . Nguyên mẫu của hàm là: long int ftell(FILEPhương pháp lập trình - Tập tin*fp);
  34. Đặt Lại Vị Trí Hiện Hành - 1 .Hàm fseek() định lại vị trí của curp dời đi một số byte tính từ đầu, từ vị trí hiện hành hay từ cuối stream là tùy vào vị trí được qui định khi gọi hàm fseek() .Nguyên mẫu của hàm là: int fseek (FILE *fp, long int offset, int origin); Phương pháp lập trình - Tập tin
  35. Đặt Lại Vị Trí Hiện Hành - 2 . origin chỉ định vị trí bắt đầu tìm kiếm và phải có giá trị như sau: Origin Vị trí trong tập tin SEEK_SET hay 0 Bắt đầu tập tin SEEK_CUR hay 1 Vị trí của con trỏ trong tập tin hiện hành SEEK_END hay 2 Cuối tập tin Phương pháp lập trình - Tập tin
  36. fprintf() và fscanf()-1 .Hệ thống nhập xuất có vùng đệm bao gồm các hàm fprintf() và fscanf() tương tự như hàm printf() và scanf() ngoại trừ rằng chúng thao tác trên tập tin .Nguyên mẫu của các hàm này là: int fprintf(FILE * fp, const char *control_string, ); int fscanf(FILE *fp, const char *control_string, ); Phương pháp lập trình - Tập tin
  37. fprintf() và fscanf() - 2 . Mặc dù fprintf() và fscanf() là cách dễ nhất nhưng không phải luôn luôn là hiệu quả nhất . Mỗi lời gọi phải mất thêm một khoảng thời gian overhead, vì dữ liệu được ghi theo dạng ASCII có định dạng chứ không phải theo định dạng nhị phân . Vì vậy, nếu tốc độ và độ lớn của tập tin là vấn đề đáng ngại, thì fread() và fwrite() sẽ là lựa chọn tốt hơn Phương pháp lập trình - Tập tin
  38. int GhiFileMangSV(char* file, SinhVien SV[], int n) { FILE* f; //khai báo con trỏ file f = fopen(file, "wb"); // mở file nhị phân if(!f) return 0; for(int i=0; i<n; i++) { fwrite(&SV[i], sizeof(SinhVien), 1, f); // ghi file } fclose(f); // đóng file return 1; } Phương pháp lập trình - Tập tin
  39. int DocFileMangSV(char* file, SinhVien SV[], int &n) { FILE* f; //khai báo con trỏ file f = fopen(file, "rb"); // mở file nhị phân if(!f) return 0; int i=0; while(!feof(f)) { if(fread(&SV[i], sizeof(SinhVien), 1, f)>0) //doc file i++; } n = i; fclose(f); // đóng file return 1; } Phương pháp lập trình - Tập tin
  40. Bài tập Lý thuyết  Có hai kiểu stream là stream ___ và stream ___.  Các tập tin đang mở được đóng lại khi chương trình bị treo hay kết thúc bất thường.(Đúng /Sai)  Hàm ___ mở một stream để dùng và liên kết một tập tin với stream đó.  Hàm được dùng để ghi ký tự vào tập tin là ___.  Hàm fgets() xem ký tự sang dòng mới như là một phần của chuỗi. (Đúng / Sai)  Hàm ___ đặt lại vị trí của con trỏ định vị bên trong tập tin về đầu tập tin. Phương pháp lập trình - Tập tin
  41. Bài tập Lý thuyết  Mỗi khi một ký tự được đọc hay ghi từ một stream, ___ được tăng lên.  Các tập tin mà trên đó hàm fread() và fwrite() thao tác thì phải được mở ở chế độ ___.  Vị trí hiện hành của con trỏ kích hoạt hiện hành có thể được tìm thấy bằng sự trợ giúp của hàm ___. Phương pháp lập trình - Tập tin
  42. Bài tập thực hành thêm 1. Viết một chương trình để nhập dữ liệu vào một tập tin và in nó theo thứ tự ngược lại. 2. Viết một chương trình để truyền dữ liệu từ một tập tin này sang một tập tin khác, loại bỏ tất cả các nguyên âm (a, e, i, o, u). Loại bỏ các nguyên âm ở dạng chữ hoa lẫn chữ thường. Hiển thị nội dung của tập tin mới. 3. Viết một chương trình C để sao chép nội dung của một tập tin vào một tập tin khác loại trừ các từ a, an, và the. 4. Viết một chương trình C để nhập vào hai chuỗi số. Lưu trữ mỗi chuỗi ở hai tập tin riêng biệt. Sắp xếp chuỗi trong mỗi tập tin. Trộn hai chuỗi vào một, sắp xếp và lưu lại chuỗi kết quả vào một tập tin mới. Hiển thị nội dung của tập tin mới. Phương pháp lập trình - Tập tin