CHƯƠNG 9 CHƯƠNG 9 TẬP TIN (FILE) TẬP TIN (FILE)
1. GIỚI THIỆU
(cid:121) C/C++ hổ trợ 2 hệ thống nhập xuất: (cid:121) 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++.
2. Streams và Files
thiết bị thiết bị Hệ thống nhập xuất của C (cid:121) Hệ thống nhập xuất của C − Cung cấp một giao diện (interface) nhất thật sự mà thật sự mà
quán độc lập với quán độc lập với chương trình tương tác. cung cấp một mức độ trừu tượng giữa lập − 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ị tượng này được gọi là stream và thiết bị thật sự được gọi là file.
3. Streams (dòng nhập xuất)
(cid:121) Hệ thống file chuyển đổi mỗi loại thành một (cid:121) Hệ thống file chuyển đổi mỗi loại thành một là stream. Tất cả stream
Hệ thống file của C được thiết kế để làm (cid:121) 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ếtbịđầucuối), các loại ổ đĩa, terminals (thiếtbịđầucuối), các loại ổ đĩa, băng từ, ...
thiết bị logic gọi có cùng hành vi có cùng hành vi
3. Streams (dòng nhập xuất)
(cid:121) Có hai loại stream: (cid:121) Có hai loại stream:
Stream độc lập với thiết bị nên cùng một (cid:121) 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 tin trên đĩa cũng có thể dùng để ghi vào loại thiết bị khác như console (mànhình).
− Văn bản (text) − Nhị phân (binary). ) h hâ (b
3.1. Text Streams
(cid:121) Ví dụ, ký tự newline ('\n') có thể bị đổi thành cặp ký tự carriage return/linefeed (ký thành cặp ký tự carriage return/linefeed (ký tựxuốngdòngvàvềđầudòng).
Một text stream là một chuổi các ký tự. (cid:121) 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. bị chuyển đổi tùy thuộc môi trường.
3.1. Text Streams
Không có quan hệ một một giữa các ký tự (cid:121) 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 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. ngoài.
3.2. Binary Streams
Một binary stream là một chuổi bytes (cid:121) 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 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ị đọc) thì bằng với số bytes trên thiết bị ngoài.
4. FILES
(cid:121) Để tạo kết nối (associate) giữa một stream (cid:121) Để 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 (cid:121) Khi file được mở, thông tin có thể được trao đổi giữa file và chương trình.
Một file có thể là một tập tin trên đĩa, một (cid:121) Một file có thể là một tập tin trên đĩa, một terminal, hay máy in.
4. FILES
(cid:121) Ví dụ, một tập tin trên đĩa (file) có thể hỗ (cid:121) 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ể. (cũng là file) thì không thể
(cid:121) “Tấtcảstreamlànhưnhaunhưngfile
Không phải tất cả file đều có cùng khả năng (cid:121) Không phải tất cả file đều có cùng khả năng như nhau.
thìkhông". thìkhông"
4. FILES
(cid:121) Qúa trình này được gọi
Để ngắt kết nối giữa một stream với một file (cid:121) Để 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 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. thiết bị ngoài.
là flushing và đảm bảo là không có thông tin bị để lại trong bảo là không có thông tin bị để lại trong vùng đệm (buffer).
4. FILES
(cid:121) Mỗi stream liên đới với một file có một cấu (cid:121) Mỗi stream liên đới với một file có một cấu
Tất cả file được tự động đóng khi chương (cid:121) 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ở 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 (halt) hay khi chương trình thực hiện hàm abort().
trúc kiểu FILE.
4.1. Cơ bản về hệ thống file
Các hàm liên quan đến file trong thư viện stdio.h Các hàm liên quan đến file trong thư viện stdio h
Tên hàm
Chức năng
Tên hàm
à
ê
Chức năng
ứ
fopen( )
Mở một file
fclose( )
Đóng một file.
putc( ) putc( )
Viết một ký tự đến một file. Viết một ký tự đến một file
fputc( )
Giống như putc() .
4.1. Cơ bản về hệ thống file
Chức năng Chức năng
Tên Tên hàm getc( ) getc( )
Đọc một ký tự từ một file. Đọc một ký tự từ một file
fgetc( )
Giống như getc() .
fgets( ) Đọc một chuổi từ một file.
fputs( ) fputs( )
Viết một chuổi đến một file. Viết một chuổi đến một file
fseek( )
Tìm một byte trong một file.
4.1. Cơ bản về hệ thống file
Chức năng
Tên hàm
ftell( )
trí hiện hành của của file
Trả về vị indicator. i di t Trả về true nếu duyệt đến cuối file (end-of-file).
feof( )
ferror( ) f ( )
Trả về true nếu một lỗi xảy ra. T ả ề
ộ lỗi ả
ế
rewind( ) Đưa indicator về đầu.
remove( ) Xóa một file.
fflush( ) fflush( )
Xả hết vùng đệm của file. Xả hết vùng đệm của file.
4.2. Con trỏ file (File pointer)
(cid:121) Con trỏ file được dùng bởi stream tương ứng để thực hiện các hoạt động nhập xuất ứng để thực hiện các hoạt động nhập xuất trên file. (cid:121) Cú pháp khai báo: Cú pháp khai báo:
Con trỏ file là một cấu trúc kiểu FILE, trỏ (cid:121) Con trỏ file là một cấu trúc kiểu FILE, trỏ đến thông tin về file như tên file, trạng thái, và vị trí hiện hành của file. và vị trí hiện hành của file.
FILE *fp;
4.3. Mở file
(cid:121) Cú pháp:
Hàm fopen() mở một stream và liên kết (cid:121) Hàm fopen() mở một stream và liên kết một file với stream đó. Hàm trả về một con trỏ file trỏ đến tập tin được mở. trỏ file trỏ đến tập tin được mở.
FILE *fopen(const char *filename, const char *mode);
(cid:121) filename: chứa tên /đường dẫn của file (cid:121) mode: cho biết mở file theo mode nào.
4.3. Mở file
Cácmode đểmởtậptin (cid:121) Cácmodeđểmởtậptin − "r" Nếu tập tin được mở thành công, hàm fopen() nạp nó vào bộ nhớ và trả về con fopen() nạp nó vào bộ nhớ và trả về con trỏ trỏ đến ký tự đầu tiên của tập tin. Ngược lại, hàm fopen() trả về NULL Ngược lại hàm fopen() trả về NULL
− "w" Nếu tập tin tồn tại, nội dung của nó
sẽ bị ghi đè sẽ bị ghi đè
4.3. Mở file
a Nếu tập tin được mở thành công hàm • "a" Nếu tập tin được mở thành công hàm fopen() nạp nó vào bộ nhớ và trả về con trỏ trỏ đến ký tự cuối cùng của tập tin. Nếu tập tin đến ký tự cuối cùng của tập tin. Nếu tập tin không tồn tại, một tập tin mới được tạo. Trả về NULL nếu không thể mở tập tin. NULL nếu không thể mở tập tin.
• "r+" Nếu tập tin được mở thành công, hàm fopen() nạp nó vào trong bộ nhớ. Trả về NULL fopen() nạp nó vào trong bộ nhớ Trả về NULL nếu không thể mở tập tin.
4.3. Mở file
(cid:121) Các hoạt động có thể làm trên tập tin: đọc, ghi thêm nội dung mới vào cuối tập tin. Không thể thêm nội dung mới vào cuối tập tin Không thể sửa đổi nội dung đang có trong tập tin.
Nếu tập tin được mở thành công, hàm a (cid:121) "a+" Nếu tập tin được mở thành công, hàm fopen() nạp nó vào bộ nhớ và trả về con trỏ trỏ đến ký tự đầu tiên của tập tin. Nếu tập tin không đến ký tự đầu tiên của tập tin. Nếu tập tin không tồn tại, một tập tin mới được tạo. Trả về NULL nếu không thể mở tập tin. nếu không thể mở tập tin.
4.3. Mở file
fopen("test txt" "w"))
Ví dụ: (cid:121) Ví dụ: FILE *fp; if((fp = fopen("test.txt","w")) == NULL) if((fp NULL) {
cout << "Cannot open file"; exit(1); exit(1);
}
4.4. Đóng file
Hàm fclose() đóng stream được mở bởi hàm (cid:121) Hàm fclose() đóng stream được mở bởi hàm fopen(). Khi hàm được gọi, nó sẽ viết bất kỳ dữ liệu nào vẫn còn trong buffer đến file rồi dữ liệu nào vẫn còn trong buffer đến file rồi đóng file. (cid:121) Cú pháp: (cid:121) Cú pháp:
int fclose(FILE *fp);
là f f − fp: là con trỏ file trả về bởi hàm fopen(). () ỏ fil ả ề bởi hà
4.5. Ghi một ký tự đến một file
(cid:121) Cú pháp: (cid:121) Cú pháp:
Có hai hàm xuất ký tự đến file là putc() và (cid:121) Có hai hàm xuất ký tự đến file là putc() và fputc(). Hai hàm này là tương đương nhau. Hàm putc() ghi một ký tự đến một file đã Hàm putc() ghi một ký tự đến một file đã được mở bởi hàm fopen().
int putc(int ch, FILE *fp);
f là f
− fp là con trỏ file trả về bởi hàm fopen() () ỏ fil ả ề bởi hà − ch là ký tự được viết đến file.
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
}
4.6. Đọc một ký tự từ một file
(cid:121) Hàm để đọc một ký tự từ file:getc() và (cid:121) Hàm để đọc một ký tự từ file:getc() và
ột ký tự từ fil đượ ỗi lầ fgetc() − Đọc mỗi lần một ký tự từ file được mở bởi ở bởi
á
ú p Đ hàm fopen() ở chế độ đọc (read). (cid:217)Cú pháp: int getc(FILE *fp); (cid:217)fp là con trỏ file kiểu FILE .
− Hàm trả về mã ascii của ký tự được đọc,
trả về EOF nếu một lỗi xảy ra. trả về EOF nếu một lỗi xảy ra.
void main() {
FILE *fp; char ch; FILE *f h h 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 putchar(ch); // in ra màn hình ch = getc(fp);
}fclose(fp); }fclose(fp);
}
3.8. Đọc và viết chuổi trên file
(cid:121) Hàm trả về str nếu đọc thành công và một
fgets(): đọc một chuổi từ stream tương (cid:121) fgets(): đọc một chuổi từ stream tương ứng cho đến khi gặp ký tự newline hay đã đọc được length 1 ký tự. đọc được length-1 ký tự.
(cid:121) Cú pháp:
con trỏ null nếu không. con trỏ null nếu không
char *fgets(char *str, int length, FILE *fp);
3.8. Đọc và viết chuổi trên file
(cid:121) Cú pháp:
fputs() ghi một chuổi trỏ đến bởi str đến (cid:121) fputs() ghi một chuổi trỏ đến bởi str đến stream trỏ đến bởi con trỏ file fp. Hàm trả về EOF nếu một lỗi xảy ra. về EOF nếu một lỗi xảy ra.
int fputs(const char *str, FILE *fp);
void main(void) {
char str[80]; FILE *fp; h t [80] FILE *f 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 */ strcat(str "\n"); /* add a newline */ fputs(str, fp); \n ); } while(*str!='\n'); } while( str!
}
4.9. Hàm fread() và fwrite()
(cid:121) Cú pháp:
Hàm fread() và fwrite() : đọc và ghi một (cid:121) Hàm fread() và fwrite() : đọc và ghi một khối của bất kỳ dữ liệu nào có kích thước lớn hơn 1 byte lớn hơn 1 byte
size_t fread(void *buffer, size_t numbytes, size_t count, FILE *fp); size_t fwrite(const void buffer, size_t numbytes, size_t count,FILE fp); size t fwrite(const void *buffer size t numbytes size t count FILE *fp);
4.10. Hàm rewind()
(cid:121) Hàm có prototype như sau: (cid:121) Hàm có prototype như sau:
Hàm rewind() di chuyển indicator đến điểm (cid:121) Hàm rewind() di chuyển indicator đến điểm bắt đầu của file.
void rewind(FILE *fp);
4.11. Hàm ferror()
(cid:121) Cú pháp: (cid:121) Cú pháp:
Hàm ferror() cho biết một hoạt động trên (cid:121) Hàm ferror() cho biết một hoạt động trên file đã gây ra lỗi.
à ộ lỗ đã ả ả ề ế
int ferror(FILE *fp); (cid:121) Hàm trả về true nếu một lỗi đã xảy ra với ớ hoạt động trên file trước khi gọi hàm ferror(), ngược lại trả về false. l f ả ề f l ()
4.12. Xóa file
Hàm remove() dùng để xóa tập tin. (cid:121) Hàm remove() dùng để xóa tập tin. (cid:121) Cú pháp:
int remove(const char *filename); int remove(const char *filename); (cid:121) Hàm trả về zero nếu xóa thành công, ngược
lại trả về nonzero l ả ề
4.13. Flushing a stream
(cid:121) Hàm trả về 0 nếu thành công, ngược lại trả ả
Hàm fflush() dùng để xuất tất cả nội dung (cid:121) Hàm fflush() dùng để xuất tất cả nội dung còn lại trong buffer của stream. (cid:121) Cú pháp: int fflush(FILE fp); (cid:121) Cú pháp: int fflush(FILE *fp); (cid:121) Hàm ghi nội dung còn trong buffer đến file fp Nếu gọi hàm fflush() không có đối số thì fp. Nếu gọi hàm fflush() không có đối số thì tất cả file đang mở.
ả ề 0 ế hà h ô à l
về EOF
5. Truy xuất file ngẫu nhiên
(cid:121) Cú pháp: (cid:121) Cú pháp:
Để đọc hay viết từ hay đến một vị trí bất kỳ (cid:121) Để đọc hay viết từ hay đến một vị trí bất kỳ trong file ta cần sự giúp đỡ của hàm fseek(). Hàm này dùng để di chuyển chỉ báo fseek(). Hàm này dùng để di chuyển chỉ báo file.
int fseek(FILE fp, long numbytes, int origin); int fseek(FILE *fp long numbytes int origin);
6. Các stream chuẩn
(cid:121) Bởi vì standard streams là các con trỏ file nên có
Khi một chương trình thực thi, ba stream được (cid:121) Khi một chương trình thực thi, ba stream được mở tự động. Đó là stdin (standard input), stdout (standard output), và stderr (standard error). stdin (standard output), và stderr (standard error). stdin dùng để đọc từ bàn phím, stdout và stderr dùng để viết đến màn hình. để viết đến màn hình.
thể dùng các hàm nhập xuất trên chúng. thể dùng các hàm nhập xuất trên chúng