Bài giảng Kỹ thuật lập trình - Bài 8: File trong C - Lê Gia Minh
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Kỹ thuật lập trình - Bài 8: File trong C - Lê Gia Minh", để 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:
- bai_giang_ky_thuat_lap_trinh_bai_8_file_trong_c.ppt
Nội dung text: Bài giảng Kỹ thuật lập trình - Bài 8: File trong C - Lê Gia Minh
- Kỹ thuật Lập Trình File trong C
- Nội dung l Stream và File l Streams văn bản và streams nhị phân l Các hàm xử lý File l Con trỏ file (File pointer) l Kết luận.
- Stream l Đối với C – cho phép coding với rất nhiều thiết bị như : máy in , dĩa mềm , dĩa cứng l Mỗi thiết bị rất khác nhau do vậy C cho phép làm việc chung nhất các thiết bị đó dưới 1 thiết bị logic : stream l Có 2 lọai stream : text và binary streams
- Text Stream ( stream văn bản ) l Stream văn bản là 1 dãy các ký tự tổ chức bởi nhiều hàng, mỗi hàng kết thúc bởi ký tự xuống hàng . l Trong stream văn bản sẽ có một số chuyển đổi như ký tự xuống hàng là ‘CR’ -13 và ‘LF’ - 10 l Do vậy sau khi chuyển đổi số lượng ký tự khi đọc ghi sẽ có thể không như nhau về mặt số lượng.
- Stream nhị phân l Binary stream là một dãy byte và không có một sự chuyển đổi nào cả . l Các hàm C đọc/ghi stream nhị phân sẽ khác với các hàm đọc ghi stream văn bản.
- Các luồng chuẩn l Trong C có khai báo nhiều luồng chuẩn, quan trọng là các luồng sau : ¡ Luồng xuất chuẩn : stdout – mặc định gắn với màn hình ¡ Luồng nhập chuẩn : stdin – mặc định gắn với bàn phím. ¡ Luồng lổi chuẩn : stderr – mặc định gắn với màn hình ¡ Các luồng này đã được tự động mở khi chương trình chạy.
- Tập tin (File) l Tập tin là 1 khái niệm lưu trữ thông tin trên thiết bị bền vững như dĩa cứng , dĩa mềm l Một file cần được liên kết với 1 stream – sau đó mới hòan tất các thao tác đọc/ghi. Việc kết gán được kết thúc khi stream đóng lại l Khi chương trình kết thúc bình thường mọi file được tự động đóng lại l Khi chương trình kết thúc không bình thường mọi file vẫn chưa đóng lại mất dữ liệu.
- Các hàm về xử lý File Name Function fopen( ) Mở file fclose( ) Đóng file fputc( ) Ghi một ký tự vào file fgetc( ) Đọc một ký tự từ file fread() Đọc một khối byte từ file vào buffer fwrite() Ghi một khối byte từ buffer vào file fseek( ) Dịch chuyển con trỏ file fprintf( ) Xuất dữ liệu có định dạng vào File fscanf( ) Nhập dữ liệu có định dạng từ File feof( ) Trả về true nếu đã đến cuối file ferror( ) Trả về true nếu đã thao tác file có lỗi rewind( ) Cho con trỏ file trở về vị trí bắt đầu remove( ) Xóa 1 file fflush( ) Ghi dữ liệu từ vùng đệm vào File
- Con trỏ FILE l Một file pointer cần phải kết gán với 1 tập tin cho phép việc đọc/ghi dữ liệu l Có một structure do C xây dựng sẳn chứa thông tin về File : FILE ( trong stdio.h) l Khai báo : l FILE *fp
- Ghi một ký tự vào File l Hàm ghi một ký tự vào file l int fputc(int ch, FILE *fp); ¡ int ch : ký tự cần ghi ¡ *fp : con trỏ đến tập tin vừa mở trước đó. l Sau khi làm việc cần đóng File l fclose(FILE *fp) ¡ Thí dụ : fclose(fp);
- Đọc một ký tự từ File l Hàm đọc ký tự từ File: l int fgetc(FILE *fp); l Hàm này trả về một ký tự đọc từ stream ( dù trả về int) l Đầu đọc file sẽ đi tới 1 ký tự.
- EOF : báo là đến cuối file (-1)
- String I/O l Hàm fputs() ghi một chuỗi vào stream l Hàm fgets() đọc 1 chuỗi từ stream – việc đọc sẽ dừng khi đọc gặp ký tự ‘\n’ hay đã đọc được length -1 ký tự l char* fputs(const char *str, FILE *fp); l char *fgets( char *str, int length, FILE *fp);
- Demo fputs l void main() l { l FILE *fp; l char str [80]; l if ((fp=fopen ("d:\\ongdo.txt", “w+")) == NULL) l { l printf ( "Cannot open file \n\n"); l exit(1); l } l clrscr (); l do l { l printf ("\nEnter a string (CR to quit): "); l gets (str); l if(strlen(str) >0) l { strcat (str, "\n"); /* add a new line */ l fputs (str, fp); l } l } while (strlen(str)>0);
- Demo fgets l printf ("\n Displaying File OngDo.Txt\"\n\n"); l rewind (fp); l while (!feof(fp)) l { l fgets (str, 80, fp); l printf ("\n%s", str); l } l fclose(fp); l } // end main
- fscanf fscanf cũng giống như scanf, ngoại trừ tham số đầu tiên của nó có kiểu stream. Để đọc một int, một float, một từ không quá 10 ký tự vào một mảng word từ bàn phím: scanf("%i%f%10s", &i, &flt, word); còn để đọc cũng như vậy từ một file: fscanf(in_stream, "%i%f%10s", &i, &flt, word); Thực tế, scanf(???) tương đương với fscanf(stdin, ???). fprintf fprintf cũng giống như printf, ngoại trừ tham số đầu tiên của nó có kiểu stream. Để ghi một int, một float (1số thập phân) , một từ canh trái trong khoảng 10 ký tự: printf("%i %.1f %-10s", i, flt, word); còn để ghi cũng như vậy vào một file: fprintf(out_stream, "%i% %.1f %-10s", i, flt, word); Thực tế, printf(???) tương đương với fprintf(stdout, ???).
- 1. #include 2. #include 3. #define PI 3.1415 4. #define RAD(k) ((k)*PI/180) 5. FILE *fp ; int k ; 6. double sinx , cosx ; 7. void main() 8. { 1. fp = fopen(“luonggiac.txt” , “wt”); 2. for(k=1 ; k<90 ; k++) 3. { 4. sinx = sin(RAD(k)) ; 5. cosx = cos(RAD(k)); 6. fprintf( fp , “\n%2d\t%10.8lf\t%10.8lf” , k , sinx , cosx); 7. } 8. fclose(fp); 9. } Thí dụ về fprintf
- 1. #include 2. FILE *fp ; 3. double sinx,cosx ; 4. void main() 5. { 1. int goc , k ; 2. fp = fopen(“luonggiac.txt” , “rt”); 3. for (k = 1 ; k<90 ; k++) 4. { 5. fscanf( fp , “%d%lf%lf” , goc , sinx , cosx); 6. fprintf( stdout , “%d %10.8lf %10.8lf \n” , goc , sinx , cosx); 7. } 8. fclose(fp); 6. }
- Đọc từ file - fread l size_t fread(void* buff, size_t bsize, size_t n, FILE* stream); ¡ Đọc n phần tử , mỗi phần tử có kích thước bsize byte từ stream vào buff ¡ Trả về số phần tử đọc được l Thí dụ đọc 1 số nguyên từ tập tin vào N ¡ int N ; ¡ int count = fread(&N , sizeof(int) ,1 , fp);
- Ghi vào file - fwrite l size_t fwrite(const void* buff, size_t bsize, size_t count, FILE* stream); ¡ Ghi từ buff vào file trỏ bởi con trỏ stream – ghi count phần tử , kích thước mỗi phần tử là bsize byte. ¡ Trả về số phần tử thật sự ghi được. l Thí dụ ghi 1 số nguyên vào file ¡ int N = 10 ; ¡ fwrite(&N , sizeof(int) , 1 , fp);
- Thí dụ copy file dùng binary stream l #include l #include l int CopyFile(char* source , char* dest); l void main() l { l char* s = "d:/ongdo.txt"; l char* d = "d:/abc.txt"; l int kq ; l clrscr(); l kq = CopyFile(s,d); l if (kq==0) printf("loi copy file "); l else printf("Ghi file thanh cong "); l getch(); l }
- Copy file (tt) l int CopyFile(char* source , char* dest) l { l FILE *fs , *fd ; l int count ; l char buff[1024]; l if ( (fs = fopen(source,"rb"))==NULL) return 0; l if ( (fd = fopen(dest,"wb"))==NULL) return 0; l while ( (count=fread(buff,1,sizeof(buff),fs))!=0) l fwrite(buff,1,count,fd); l fclose(fs); l fclose(fd); l return 1 ; l }
- Fseek – di chuyển đầu đọc l int fseek(FILE* stream, long offset, int whence); l Tham số thứ hai, có kiểu long là vị trí ta muốn chuyển đến. Nếu ta muốn chuyển đến byte thứ 30 trong file (không quan tâm đến vị trí hiện tại): ¡ fseek(stream, 30L, SEEK_SET); l SEEK_SET : “di chuyển tính từ đầu file”. l SEEK_CUR : “di chuyển tính từ vị trí hiện hành”. l SEEK_END : “di chuyển tính từ cuối file”. l Khi dùng SEEK_SET, vị trí chỉ định phải không âm. Khi dùng SEEK_CUR, vị trí chỉ định có thể âm hoặc dương. Khi dùng SEEK_END, vị trí chỉ định phải âm. Hàm ftell có thể được dùng để xác định vị trí hiện tại trong file.
- fsetpos và fgestpost l Một vấn đề cơ bản với fseek và ftell ở chỗ trị tối đa của một số long là 231-1. Nghĩa là ta chỉ có thể di chuyển đến một vị trí bên trong một file 2.1 Gigabyte. Nếu file lớn hơn sẽ rắc rối. Để giải quyết việc này, thư viện chuẩn cung cấp hai hàm khác: l int fgetpos(FILE *stream, fpos_t *pos); l int fsetpos(FILE *stream, const fpos_t *pos); l Ở đây fpos_t là một kiểu cài đặt riêng cho phép giữ một vị trí bên trong một file kích thước tùy ý. Tuy nhiên, fgetpos phải được gọi để khởi tạo (lấy vị trí lần đầu) một fpos_t trước khi fsetpos có thể được gọi để dùng fpos_t.
- ftell l long ftell(FILE* stream); ¡ Cho ta khỏang cách tính bằng byte giữa vị trí hiện tại của đầu đọc so với vị trí đầu file. ¡ fseek(fp, 0L, SEEK_END); ¡ long kichthuoctaptin = ftell(fp);
- Thí dụ về đọc ghi struct l #include l #include l typedef struct { l char hoten [30]; l char diachi [40]; l long sodt; l }structSV; l int writeFile(structSV[]); l int readFile(structSV[]);
- l void main () l { l structSV sv[3]; l int i; l printf("Input the students' detailed information:\n"); l for(i=0; i<3; i++){ l printf("\nStudent no. %d :\n",i+1); l printf("Full name : "); gets(sv[i].hoten); flushall(); l printf("Address : "); gets(sv[i].diachi); fflush(stdin); l printf("Phone no : "); scanf("%ld",&sv[i].sodt); fflush(stdin); l } l if(writeFile(sv)){ l printf("cannot open file to write"); l exit(1); l } l if (readFile(sv)) l { l printf("cannot open file to read"); l exit(1); l } l }
- Hàm ghi file l int writeFile(structSV s[]) l { l FILE *fp; l int i; l if (( fp= fopen ("d:\\ds.txt", "wb+")) == NULL ) l { l return(1); l } l printf("\nWrite to file "); l for(i=0; i<3; i++){ l fwrite (&s[i], sizeof(s[i]), 1,fp); l } l fclose (fp); l return 0; l }
- Hàm đọc file l int readFile(structSV s[]) l { l FILE *fp; l int i; l if ((fp= fopen ("d:\\ds.txt", "rb+")) == NULL ) exit(1); l printf("\nList of student"); l printf ("\n%-25s %-30s %s", "Full name", "Address", "Phone"); l for(i=0;i<3;i++){ l fread (&s[i], sizeof(s[i]), 1, fp); l printf ("\n%-25s %-30s %ld", s[i].hoten, s[i].diachi, s[i].sodt); l } l fclose (fp); l return 0; l }