Lập trình hướng đối tượng - 24


Số thực 678.0 được in: 678

+ Khi ios::fixed bật và cờ ios::showpoint bật thì số thực in ra dưới dạng thập phân, số chữ số phần phân (sau dấu chấm) được in ra đúng bằng độ chính xác n.

Ví dụ nếu độ chính xác n = 4 thì:

Số thực -87.1500 được in: -87.1500

Số thực 23.45425 được in: 23.4543

Số thực 678.0 được in: 678.0000

+ Khi ios::scientific bật và cờ ios::showpoint tắt thì số thực in ra dưới dạng mũ (dạng khoa học). Số chữ số phần phân (sau dấu chấm) cđa phần định trị được tính bằng độ chính xác n nhưng khi in thì bỏ đi các chữ số 0 ở cuối.

Ví dụ nếu độ chính xác n = 4 thì:

Số thực -87.1500 được in: -8.715e+01

Có thể bạn quan tâm!

Xem toàn bộ 256 trang tài liệu này.

Số thực 23.45425 được in: 2.3454e+01 Số thực 678.0 được in: 6.78e+02

+ Khi ios::scientific bật và cờ ios::showpoint bật thì số thực in ra dưới dạng mũ. Số chữ số phần phân (sau dấu chấm) cđa phần định trị được in đúng bằng độ chính xác n.

Lập trình hướng đối tượng - 24

Ví dụ nếu độ chính xác n = 4 thì:

Số thực -87.1500 được in: -8.7150e+01 Số thực 23.45425 được in: 2.3454e+01 Số thực 678.0 được in: 6.7800e+01

Nhóm 4: gồm các hiển thị

ios::showpos, ios::showbase, ios::uppercase

Cờ ios::showpos

+ nếu cờ ios::showpos tắt (mặc định) thì dấu cộng không được in trước số dương.

+ nếu cờ ios::showpos bật thì dấu cộng được in trước số dương.

Cờ ios::showbase


+ nếu cờ ios::showbase bật thì số nguyên hệ 8 được in bắt đầu bằng ký tự 0 và số nguyên hệ 16 được bắt đầu bằng các ký tự 0x. Ví dụ nếu a = 40 thì:

dạng in hệ 8 là: 050 dạng in hệ 16 là 0x28

+ nếu cờ ios::showbase tắt (mặc định) thì không in 0 trước số nguyên hệ 8 và không in 0x trước số nguyên hệ 16. Ví dụ nếu a = 40 thì:

dạng in hệ 8 là: 50

dạng in hệ 16 là 28

Cờ ios::uppercase

+ nếu cờ ios::uppercase bật thì các chữ số hệ 16 (như A, B, C, ...) được in dưới dạng chữ hoa.

+ nếu cờ ios::uppercase tắt (mặc định) thì các chữ số hệ 16 (như A, B, C, ...)

được in dưới dạng chữ thường.


5.5.3. Các phương thức bật tắt cờ

Các phương thức này định nghĩa trong lớp ios.

Cú pháp: long cout.setf(long f);

Chức năng: Bật các cờ liệt kê trong f và trả về một giá trị long biểu thị các cờ

đang bật. Thông thường giá trị f được xác định bằng cách tổ hợp các cờ. Ví dụ câu lệnh:

cout.setf(ios::showpoint | ios::scientific) ; sẽ bật các cờ ios::showpoint và ios::scientific. Cú pháp: long cout.unsetf(long f);

Chức năng: Tắt các cờ liệt kê trong f và trả về một giá trị long biểu thị các cờ

đang bật. Thông thường giá trị f được xác định bằng cách tổ hợp các cờ. Ví dụ câu lệnh:

cout.unsetf(ios::showpoint | ios::scientific); sẽ tắt các cờ ios::showpoint và ios::scientific.

Cú pháp: long cout.flags(long f);


Chức năng: Giống như cout.setf(long). Ví dụ câu lệnh: cout.flags(ios::showpoint | ios::scientific) ;

sẽ bật các cờ ios::showpoint và ios::scientific.

Cú pháp: long cout.flags();

Chức năng: Trả về một giá trị long biểu thị các cờ đang bật.


5.6. Các dòng tin chuẩn

Để nhập, xuất dữ liệu lên tệp, chúng ta cần tạo các dòng tin mới (khai báo các

đối tượng stream) và gắn chúng với một tập tin cụ thể. C++ cung cấp 3 lớp stream để làm điều này:

Lớp ofstream: dùng để tạo các dòng xuất (ghi tệp)

Lớp ifstream: dùng để tạo các dòng nhập (đọc tệp)

ostream

Lớp fstream: dùng để nhập, xuất hoặc cả nhập và xuất Sơ đồ dẫn xuất như sau:


ios

fstreambase

istream



ofstream

fstream


ifstream

Sơ đồ 5.2

5.7. Ghi dữ liệu lên tệp


Trong C++, khi thao tác với một tệp dữ liệu, cần thực hiện tuần tự theo các bước như sau:

1) Mở tệp tin

2) Thực hiện các thao tác đọc, ghi trên tệp tin đang mở

3) Đóng tệp tin


Để thực hiện các thao tác liên quan đến tệp dữ liệu, C++ cung cấp một thư viện <fstream.h> chứa các lớp và các hàm phục vụ cho các thao tác này. Do vậy, trong các chương trình làm việc với tệp tin, ta cần khai báo chỉ thị dùng thư viện này ngay từ đầu chương trình: #include<fstream.h>

Khai báo biến tệp

Trong C++, khi khai báo một biến tệp, đồng thời ta sẽ mở tệp tương ứng theo cú pháp tổng quát bằng cách dùng kiểu fstream như sau:

fstream <Tên biến tệp>(<Tên tệp>, <Chề độ mở tệp>); Trong đó:

Tên biến tệp: có tính chất như một tên biến thông thường, nó sẽ được dùng để thực hiện các thao tác với tệp gắn với nó. Tên biến tệp cũng phải tuân thđ theo quy tắc đặt tên biến trong C++.

Tên tệp: là tên tệp dữ liệu mà ta cần thao tác trên nó.

Chề độ mở tệp: là các hằng kiểu bít đã được định nghĩa sẵn bởi C++. Nó chỉ ra rằng ta đang mở tệp tin ở chề độ nào: đọc hoặc ghi, hoặc cả đọc lẫn ghi.

Ví dụ, khai báo:

fstream myFile(abc.txt, ios::in);

là khai báo một biến tệp, có tên là myFile, dùng để mở tệp tin có tên là abc.txt và tệp tin này được mở ở chề độ để đọc dữ liệu (bít chỉ thị ios::in).

Lưu ý:

Tên tệp tin có dạng một chuỗi kí tự, nếu khai báo tên tệp có đường dẫn thư mục thì mỗi dấu phải được viết thành để tránh bị nhầm lẫn với các kí tự đặc biệt trong C như n, d” …Ví dụ, muốn mở một tệp tên là abc.txt trong thư mục myDir để đọc, ta phải khai báo như sau:

fstream myFile(myDirabc.txt, ios::in);

Các chề độ mở tệp tin

Các chề độ mở tệp tin được định nghĩa bởi các bít chỉ thị:

ios::in: Mở một tệp tin để đọc.

ios::out: Mở một tệp tin có sẵn để ghi.

ios::app: Mở một tệp tin có sẵn để thêm dữ liệu vào cuối tệp. ios::ate: Mở tệp tin và đặt con trỏ tệp tin vào cuối tệp. ios::trunc: nếu tệp tin đã có sẵn thì dữ liệu cđa nó sẽ bị mất. ios::nocreate: Mở một tệp tin, tệp tin này bắt buộc phải tồn tại.


ios::noreplace: Chỉ mở tệp tin khi tệp tin chưa tồn tại. ios::binary: Mở một tệp tin ở chề độ nhị phân. ios::text: Mở một tệp tin ở chề độ văn bản.

Khi muốn mở một tệp tin đồng thời ở nhiều chề độ khác nhau, ta kết hợp các bít chỉ thị tương ứng bằng phép toán hợp bít |. Ví dụ, muốn mở một tệp tin abc.txt để đọc (ios::in) đồng thời với để ghi (ios::out) dưới chề độ văn bản (ios::text), ta khai báo như sau:

fstream myFile(abc.txt, ios::in|ios::out|ios::text);

Để mở một tệp tin dưới chề độ văn bản, ta dùng cú pháp sau: fstream <Tên biến tệp>(<Tên tệp>, ios::text);

Khi đó, các thao tác đọc, ghi trên biến tệp được thực hiện theo đơn vị là các từ,

được phân cách bởi dấu cách (space bar) hoặc dấu xuống dòng (enter). Ví dụ, muốn mở tệp tin baitho.txt dưới chề độ văn bản, ta khai báo như sau:

fstream myBaiTho(baitho.txt, ios::text);

Để mở một tệp tin dưới chề độ nhị phân, ta dùng cú pháp sau: fstream <Tên biến tệp>(<Tên tệp>, ios::binary);

Khi đó, các thao tác đọc, ghi trên biến tệp được thực hiện theo đơn vị byte theo kích thước các bản ghi (cấu trúc) được ghi trong tệp. Ví dụ, muốn mở tệp tin baitho.txt dưới chề độ nhị phân, ta khai báo như sau:

fstream myBaiTho(baitho.txt, ios::binary);

Ghi tệp văn bản bằng <<

Các bước thực hiện để ghi dữ liệu vào một tệp tin như sau:

B1. Mở tệp tin theo chề độ để ghi bằng đối tượng ofstream (mở tệp tin chỉ để ghi):

ofstream <Tên biến tệp>(<Tên tệp tin>, ios::out); B2. Ghi dữ liệu vào tệp bằng toán tử <<:

<Tên biến tệp> << <Dữ liệu>; B3. Đóng tệp tin bằng lệnh close():

<Tên biến tệp>.close();

C++ cho phép chúng ta định nghĩa chồng toán tử ghi tệp (<<) trên dữ liệu kiểu

đối tượng. Khi đó, ta phải định nghĩa một hàm toán tử là hàm bạn cđa lớp. Ví dụ ta định nghĩa chồng toán tử ghi tệp trên dữ liệu kiểu đối tượng lớp ts đã được đề cập đến trong ví dụ 5.3 như sau:


Ví dụ 5.5:

class ts

{

char sbd[5]; char ten[30];

unsigned int diem; public:

friend ofstream &operator<<(ofstream &fs, const ts &t)

{


}

....

};

fs<<t.sbd<<endl; fs<<t.ten<<endl; fs<<t.diem<<endl; return fs;

Ghi dữ liệu vào một tệp nhị phân

Để ghi dữ liệu vào tệp nhị phân, ta thực hiện các bước sau:

B1. Mở tệp tin theo chề độ để ghi nhị phân bằng đối tượng fstream: fstream <Tên biến tệp>(<Tên tệp tin>, ios::out|ios::binary);

B2. Ghi dữ liệu vào tệp bằng lệnh write():

<Tên biến tệp>.write(char* <Dữ liệu>, int <Kích thước dữ liệu>); B3. Đóng tệp tin bằng lệnh close():

<Tên biến tệp>.close();

Trong đó, lệnh write nhận hai tham số đầu vào như sau:

Tham số thứ nhất là con trỏ kiểu char trỏ đến vùng dữ liệu cần ghi vào tệp. Vì con trỏ bắt buộc có kiểu char nên khi muốn ghi dữ liệu có kiểu khác vào tệp, ta dùng hàm chuyển kiểu:

reinterpret_cast<char *>(<Dữ liệu>);

Tham số thứ hai là kích cỡ dữ liệu được ghi vào tệp. Kích cỡ này được tính theo byte, nên thông thường ta dùng toán tử:

sizeof(<Kiểu dữ liệu>);

Lưu ý:


Khi muốn đọc, ghi các dữ liệu có cấu trúc (struct) vào tệp thì ta phải dùng ở chề độ đọc/ghi tệp nhị phân mà không thể dùng chề độ đọc/ghi ở chề độ văn bản. Khi đọc/ghi dữ liệu có kiểu cấu trúc, để toán tử sizeof() thực hiện chính xác thì các trường cđa cấu trúc không được là kiểu con trỏ. Vì toán tử sizeof() đối với con trỏ chỉ cho kích cỡ cđa con trỏ mà không cho kích cỡ thật cđa vùng dữ liệu

mà con trỏ trỏ tới.

Chương trình sau minh hoạ việc ghi dữ liệu vào tệp tin nhị phân, dữ liệu là kiểu cấu trúc. Tên tệp tin và số lượng bản ghi được người dùng tự nhập vào từ bàn phím. Chương trình sẽ ghi vào tệp các bản ghi có cấu trúc do người dùng gõ vào từ bàn phím.

Ví dụ 5.6:

#include<stdlib.h>

#include<iostream.h>

#include<fstream.h>

#include<conio.h>

#include<type.h>

const int length = 25; // Độ dài tối đa tên tệp tin typedef struct

{

int day; // Ngày

int month; // Tháng int year; // Năm

} Date; typedef struct

{

char name[20]; // Tên nhân viên

Date birthDay; // Ngày sinh cđa nhân viên char role[20]; // Chức vụ cđa nhân viên float salary; // Lương cđa nhân viên

} Employee; void main()

{

clrscr();


char fileName[length]; // Tên tệp tin cout << Ten tep tin: ;

cin >> setw(length) >> fileName; // Nhập tên tệp tin int recordNumber; // Số lượng bản ghi

cout << So luong ban ghi: ;

cin >> recordNumber; // Nhập số lượng bản ghi

/* Mở tệp tin */

// Khai báo và mở tệp tin

fstream fileOut(fileName, ios::out|ios::binary); if(!fileOut) // Không mở được tệp

{

cout << Khong the tao duoc tep tin << fileName << endl; exit(1);

}

/* Ghi dữ liệu vào tệp tin */ Employee myEmployee;

for(int i=0; i<recordNumber; i++)

{

cout << Ban ghi thu << i+1 << endl; cout << Name: ;

cin >> myEmployee.name; // Nhập tên nhân viên cout << Day of birth: ;

cin >> myEmployee.birthDay.day;// Nhập ngày sinh cout << Month of birth: ;

cin >> myEmployee.birthDay.month;// Nhập tháng sinh cout << Year of birth: ;

cin >> myEmployee.birthDay.year;// Nhập năm sinh cout << Role: ;

cin >> myEmployee.role; // Nhập chức vụ cout << Salary: ;

cin >> myEmployee.salary; // Nhập tiền lương

// Ghi dữ liệu vào tệp fileOut.write(reinterpret_cast<char *>(&myEmployee),

..... Xem trang tiếp theo?
⇦ Trang trước - Trang tiếp theo ⇨

Ngày đăng: 03/07/2022