Lập trình hướng đối tượng với C++ - Phụ lục 1: Các kênh xuất nhập

 

1. Giới thiệu chung 265

1.1 Khái niệm về kênh 265

1.2 Thư viện các lớp vào ra 265

2. Lớp ostream 266

2.1 Định nghĩa chồng toán tử << trong lớp ostream 266

2.2 Hàm put 266

2.3 Hàm write 267

2.4 Khả năng định dạng 267

2.4.1 Chọn cơ số thể hiện 267

2.4.2 Đặt độ rộng 268

3. Lớp istream 270

3.1 Định nghĩa chồng toán tử “>>” trong lớp istream 270

3.2 Hàm thành phần get 271

3.3 Các hàm thành phần getline và gcount 272

3.4 Hàm thành phần read 272

3.5 Một số hàm khác 273

4. Trạng thái lỗi của kênh nhập 273

4.1 Các cờ lỗi 273

4.2 Các thao tác trên các bit lỗi 274

4.2.1 Đọc giá trị 274

4.2.2 Thay đổi trạng thái lỗi 274

4.3 Định nghĩa các toán tử () và ! 274

5. Quản lý định dạng 275

5.1 Trạng thái định dạng của một dòng 275

5.2 Từ trạng thái định dạng 276

5.3 Thao tác trên trạng thái định dạng 277

5.3.1 Các toán tử thao tác định dạng không tham số (TTĐDKTS) 278

5.3.2 Các toán tử định dạng có tham số(TTĐDCTS) 278

5.3.3 Các hàm thành phần 279

6. Liên kết kênh xuất/nhập với một tập tin 280

6.1 Liên kết xuất với một tập tin 280

6.2 Liên kết kênh nhập với một tập tin 282

6.3 Các khả năng truy nhập trực tiếp 283

6.4 Các chế độ mở tập tin khác nhau 286

 

 

doc24 trang | Chuyên mục: C/C++ | Chia sẻ: dkS00TYs | Lượt xem: 1614 | Lượt tải: 0download
Tóm tắt nội dung Lập trình hướng đối tượng với C++ - Phụ lục 1: Các kênh xuất nhập, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
ator
Kết quả thực hiện cho ta tham chiếu đến kênh hiện tại, do vậy đó cho phép xử lý chúng như cách thức chuyển thông tin. Đặc biệt nó còn cho phép áp dụng nhiều lần liên tiếp các toán tử “>”.
Sau đây là danh sách các toán tử định dạng không tham số:
TTĐDKTS
Sử dụng trong các kênh
Hoạt động
dec
vào/ra
Kích hoạt cờ cơ số biểu diễn hệ 10
hex
vào/ra
Kích hoạt cờ cơ số biểu diễn hệ 16
oct
vào/ra
Kích hoạt cờ cơ số biểu diễn hệ 8
ws
vào
Kích hoạt cờ skipws 
endl
ra
Thêm dấu xuống dòng
ends
ra
Thêm ký tự kết thúc xâu
flush
ra
Làm rỗng bộ đệm
Các toán tử định dạng có tham số(TTĐDCTS)
Các toán tử này được khai báo trong các lớp ostream, istream dưới dạng hàm thành phần:
istream &manipulator(argument)
hoặc
ostream &manipulator(argument)
Các toán tử này được sử dụng giống như các toán tử định dạng không có tham số. Tuy nhiên, muốn sử dụng chúng phải tham chiếu tập tin tiêu đề iomaip.h bằng chỉ thị:
#include 
Sau đây là danh sách các toán tử định dạng có tham số:
TTĐDCTS
Sử dụng cho các dòng
Vai trò
setbase(int)
vào/ra
Định nghĩa cơ số hiển thị
resetiosflags(long)
vào/ra
Đặt lại 0 tất cả các bit có mặt trong tham số
setiosflags(long)
vào/ra
Kích hoạt các bit có trong tham số
setfill(int)
vào/ra
định nghĩa lại ký tự độn
setprecision(int)
vào/ra
Định nghĩa độ chính xác cho các số thực
setw(int)
vào/ra
Định nghĩa độ rộng
Các hàm thành phần
Trong hai lớp istream và ostream có bốn hàm thành phần: setf, fill, precision, và width được mô tả như sau:
Hàm setf 
Hàm này cho phép thay đổi từ trạng thái định dạng. Hàm này có hai phiên bản khác nhau:
long setf(long)
lời gọi tới phiên bản này kích hoạt các cờ được mô tả trong tham số. Giá trị trả về của hàm là trạng thái cũ của từ trạng thái định dạng. Lưu ý rằng hàm này không tác động đến các cờ không được mô tả. Như vậy, với fl biểu thị một kênh, chỉ thị:
fl.setf(ios::oct);
sẽ kích hoạt cờ oct. Tuy nhiên, rất có thể các cờ khác như dec hay hex vẫn còn tác dụng. Dạng thứ hai của hàm setf hay được sử dụng trong thực tế là:
long setf(long, long)
Lời gọi tới phiên bản này kích hoạt các cờ mô tả trong tham số thứ nhất ở trong tham số thứ hai. Chẳng hạn, nếu fl là một kênh, chỉ thị sau:
fl.setf(ios::oct,ios::basedfield);
sẽ kích hoạt cờ ios::oct và tắt các cờ khác trong ios::basefield.
Giá trị trả về của lời gọi này là giá trị cũ của tham số thứ hai.
Hàm fill
Hàm này cho phép xác định và xác lập lại ký tự độn. Cũng có hai phiên bản khác nhau cho hàm này:
char fill()
Phiên bản này trả về ký tự độn hiện đang được sử dụng, trong khi đó
char fill(char)
được sử dụng để thay đổi ký tự độn.
Hàm precision
Hàm này cho phép xác định hoặc xác lập lại độ chính xác biểu diễn số thực. Hai phiên bản khác nhau cho hàm là:
int precision()
sẽ trả về giá trị mô tả độ chính xác hiện thời, còn 
int precision(int)
đặt lại độ chính xác mới, đồng thời trả về giá trị cũ.
Hàm width
Hàm này cho phép xác định hay xác lập lại độ rộng của trường hiển thị thông tin. Cũng có hai phiên bản khác nhau:
int width()
sẽ trả về độ rộng đang được sử dụng hiện tại, còn
int width(int)
sẽ trả về độ rộng hiện thời đồng thời xác lập độ rộng mới là tham số được mô tả trong lời gọi hàm.
Liên kết kênh xuất/nhập với một tập tin
Mục này trình bày cách để chuyển hướng vào ra tới một tập tin, đồng thời cũng giới thiệu các khả năng truy nhập trực tiếp vào các tập tin.
Liên kết xuất với một tập tin
Để liên kết một kênh xuất với một tập tin, ta chỉ cần tạo một đối tượng kiểu lớp ofstream, một lớp kế thừa từ ofstream. Việc sử dụng lớp này cần tới tập tin tiêu đề fstream.h.
Hàm thiết lập của lớp ofstream có hai tham số:
- tên của tập tin liên quan(dưới dạng một xâu ký tự)
- chế độ mở tập tin được xác định bởi một số nguyên.
Lớp ios có định nghĩa một số giá trị mô tả các chế độ mở tập tin khác nhau. Chỉ thị sau đây là một ví dụ minh hoạ:
ofstream output(“abc.txt”,ios::out);
Khi đó, đối tượng output sẽ được liên kết với tập tin tên là abc.txt, tập tin này được mở ở chế độ ghi. Sau khi đã tạo được một đối tượng ofstream, việc ghi ra tập tin được thực hiện giống như kết xuất ra một kênh xuất, chẳng hạn:
output<<12<<“abc”<<endl;
Có thể kiểm tra trạng thái lỗi của dòng xuất tương ứng với tập tin giống như cách ta đã dùng đối với các kênh xuất chuẩn:
if(output) ...
Chương trình ví dụ sau mô tả cách thức ghi một số số nguyên vào một tập tin.
/*io2.cpp*/
#include 
#include 
#include 
#include 
#include 
const int LGMAX = 20;
void main() {
 clrscr();
 char filename[LGMAX+1];
 int n;
 cout<<"Ten tap tin : ";
 cin>>setw(LGMAX)>>filename;
 ofstream output(filename,ios::out);
 if (!output) {
 cout<<"Khong the tao duoc tap tin\n";
 exit(1);
 }
 do {
 cin >>n;
 if (n>0) output<<n<<' ';
 }while(n>0 && (output));
 output<<endl;
 output.close();
}
Liên kết kênh nhập với một tập tin
Một đối tượng của lớp ifstream sẽ được sử dụng để liên kết với một tập tin chứa thông tin cần nhập. Giống như ofstream, lớp ifstream cũng được định nghĩa trong tập tiêu đề fstream.h. Lớp ifstream có hàm thiết lập với hai tham số giống như ofstream. Chỉ thị sau đây sẽ liên kết một đối tượng ifstream với tập tin abc.txt:
ifstream input(“abc.txt”,ios::in);
Việc sử dụng input để đọc nội dung abc.txt giống hệt như việc sử dụng cin để đọc dữ liệu từ bàn phím. Ta xét ví dụ sau:
/*io3.cpp*/
#include 
#include 
#include 
#include 
#include 
const int LGMAX = 20;
void main() {
 clrscr();
 char filename[LGMAX+1];
 int n;
 cout<<"Ten tap tin : ";
 cin>>setw(LGMAX)>>filename;
 ifstream input(filename,ios::in);
 if (!input) {
 cout<<"Khong the mo duoc tap tin\n";
 exit(1);
 }
 while(input) {
 input>>n;
 cout<<n<<endl;
 }
 input.close();
}
Nhận xét
Lớp fstream (thừa kế từ hai lớp ifstream và ofstream) dùng để định nghĩa các kênh dữ liệu thực hiện đồng thời cả hai chức năng nhập và xuất trên một tập tin. Việc khai báo một đối tượng kiểu fstream cũng giống như khai báo đối tượng ofstream và ifstream. Chỉ thị:
fstream file(“abc.txt”,ios::in|ios::out);
sẽ gắn đối tượng file với tập tin abc.txt, được mở để đọc và ghi đồng thời.
Các khả năng truy nhập trực tiếp
Việc truy nhập (đọc/ghi) đến tập tin dựa trên một phần tử là con trỏ tập tin. Tại mỗi thời điểm, con trỏ tập tin xác định một vị trí tại đó thực hiện thao tác truy nhập. Có thể xem con trỏ này như cách đếm số phim trong máy ảnh. Sau mỗi một thao tác truy nhập, con trỏ tập tin tự động chuyển sang vị trí tiếp theo giống như việc lên phim mỗi khi bấm máy ảnh. Ta gọi cách truy nhập tập tin kiểu này là truy nhập tuần tự. Các chương trình io2.cpp, io3.cpp sử dụng cách truy nhập này để đọc và ghi thông tin trên các tập tin. Nhược điểm của cách truy nhập tuần tự là phải đi từ đầu tập tin qua các tất cả các phần tử có trong tập tin để đi đến được phần tử cần thiết, do vậy tốn không ít thời gian. Cách truy nhập trực tiếp sẽ cho phép đến thẳng tới phần tử chúng ta cần nhờ sử dụng một số hàm thành phần thích hợp trong các lớp ifstream và ofstream.
Trong lớp ifstream có hàm seekg và trong lớp ofstream có hàm seekp được dùng để di chuyển con trỏ tập tin. Mỗi hàm thành phần đó có hai tham số:
- Tham số thứ nhất là số nguyên mô tả dịch chuyển (tính theo byte) con trỏ bao nhiêu vị trí so với vị trí gốc, được mô tả bởi tham số thứ hai (xem hai hàm fseek trong stdio.h).
- Tham số thứ hai lấy một trong ba giá trị sau:
ios::beg
vị trí gốc là đầu tập tin
ios::cur
vị trí gốc là vị trí hiện thời của con trỏ tập tin
ios::end
vị trí gốc là cuối tập tin.
Hai hàm tellg (đối với ifstream) và tellp (đối với ofstream) dùng để xác định vị trí hiện thời của các con trỏ tập tin. 
Chương trình sau đây minh hoạ khả năng truy nhập tập tin trực tiếp.
/*io4.cpp*/
#include 
#include 
#include 
#include 
#include 
const int LGMAX = 20;
void main() {
 clrscr();
 char filename[LGMAX+1];
 int n,num;
 cout<<"Ten tap tin : ";
 cin>>setw(LGMAX)>>filename;
 ifstream input(filename,ios::in);
 if(!input) {
 cout<<"Khong mo duoc tap tin";
 exit(1);
 }
 do {
 cout<<"So thu tu cua so nguyen se tim : ";
 cin>>num;
 if (num >0) {
 input.seekg(sizeof(int)*(num-1),ios::beg);
 input>>n;
 if (input) cout<<"--Gia tri : "<<n<<endl;
 else {
	cout<<"--Loi\n";
	input.clear();
	}
 }
 } while(num);
 input.close();
}
Ten tap tin : abc.txt
So thu tu cua so nguyen se tim : 3
--Gia tri : 3
So thu tu cua so nguyen se tim : 2
--Gia tri : 22
So thu tu cua so nguyen se tim : 1
--Gia tri : 1
So thu tu cua so nguyen se tim : 3
--Gia tri : 3
So thu tu cua so nguyen se tim : 4
--Gia tri : 3
So thu tu cua so nguyen se tim : 5
--Gia tri : 4
So thu tu cua so nguyen se tim : 6
--Gia tri : 3
So thu tu cua so nguyen se tim : 7
--Gia tri : 2
So thu tu cua so nguyen se tim : 6
--Gia tri : 3
So thu tu cua so nguyen se tim : 100
--Loi
So thu tu cua so nguyen se tim : 0
Các chế độ mở tập tin khác nhau
Chế độ
Mô tả hành động tương ứng
ios::in
Mở một tập tin để đọc(bắt buộc đối với ifstream)
ios::out
Mở một tập tin để ghi(bắt buộc đối với ofstream)
ios::app
Mở một tập tin để gắn thêm các thông tin vào cuối.
ios::ate
Đặt con trỏ tập tin vào cuối tập tin
ios::trunc
Nếu tập tin đã có, nội dung của nó sẽ bị mất.
ios::nocreate
Tập tin bắt buộc phải tồn tại.
ios::noreplace
Tập tin chưa tồn tại
ios::binary
Tập tin được mở ở chế độ nhị phân Trong các môi trường dos và windows người ta phân biệt các tập tin văn bản và tập tin nhị phân. Khi mở một tập tin phải xác định ngay là liệu chúng ta sẽ làm việc với các tập tin loại nào. Sự phân biệt này về thực chất liên quan đến việc xử lý ký tự cuối dòng. 
ios::text
Tập tin được mở ở chế độ văn bản.
Để thực hiện được nhiều hành động trên cùng một tập tin phải tổ hợp các bit mô tả chế độ bằng cách sử dụng toán tử | (cộng bit).
Chẳng hạn: 
fstream f(“abc.txt”,ios::in|ios::out);

File đính kèm:

  • docLập trình hướng đối tượng với C++ - Phụ lục 1 Các kênh xuất nhập.DOC