1. Trang chủ
  2. » Luận Văn - Báo Cáo

BÁO CÁO LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG Tìm hiểu về vào ra với tệp nhị phân (binary file)

21 417 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 21
Dung lượng 124,5 KB

Nội dung

Mở tệp Để mở một tệp tin dưới chế độ nhị phân, ta dùng cú pháp sau: Fstream Tên_tệp>, ios::binary; Khi đó, các thao tác đọc ghi tên biến tệp được thực hiện theo đơn vị byte theokích thướ

Trang 1

MỤC LỤC

I Mở đầu: 1

Khái niệm về tệp: 2

1 Mở tệp 2

2 Vào ra tệp nhị phân bằng hàm read() và write() 2

I

I Mở đầu:

Một số đặc điểm chung về tệp

Trang 2

Để 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 quátrình làm việc với tệp tin, chúng ta cần khai báo chỉ thị dùng thư viện ngay từ đầuchương trình như sau:

#include<fstream.h>

II Nội dung

1 Tìm hiểu về vào/ra với tệp nhị phân (binary file)

1 Mở tệp

Để 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 tên biến tệp được thực hiện theo đơn vị byte theokích thước các bản ghi (cấu trúc) được ghi trong tệp

Ví dụ: khi ta muốn mở tệp tin baitho.txt dưới chế độ nhị phân thì ta khai báo nhưsau:

Fstream MyBaiTho(“baitho.txt”, ios::binary);

2 Vào ra tệp nhị phân bằng hàm read() và write()

a) Ghi vào tệp nhị phân bằng hàm write()

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

- 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);

- Ghi dữ liệu vào tệp bằng hàm “write()”:

Trang 3

<tên_biến_tệp>.write(char* <dữ liệu>, int <kích thước dữ liệu>);

- Đóng tệp tin bằng lệnh close():

<tên_biến_tệp>.close();

Trong đó, thao tác 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ùnghàm chuyển kiể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 thành viên 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

b) Đọc dữ liệu từ tệp nhị phân bằng hàm read()

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

- Mở tệp tin theo chế độ để đọc tệp nhị phân bằng đối tượng fstream:

fstream <tên_biến_tệp>(tên_tệp_tin>, ios::in | ios::binary);

- Để mở tệp theo chế độ nhị phân và ghi bổ sung vào tệp chúng ta có thểlàm một trong 2 cách sau:

+C.1 Khai báo theo mẫu sau:

fstream <tên_biến_tệp>(tên_tệp_tin>, ios::in | ios::binary | ios::app );//ở đây app nghĩa là append (ghi bổ sung)

+ C.2 Tạo đối tượng tệp

Fstream f;

Sau đó dùng hàm open() để mở tệp:

f.open("sv.dl",ios::binary | ios::app);

Trang 4

Ngoài ra bạn có thể ghi tệp nhị phân dưới nhiều chế độ khác nhau như đãnói ở mục 3 trong phần I.

- Đọc dữ liệu vào tệp bằng hàm “read()”:

<tên_biến_tệp>.read(char* <dữ liệu>, int <kích thước dữ liệu>);

- Đóng tệp tin bằng lệnh close():

<tên_biến_tệp>.close();

2 Vào ra trực tiếp với bộ nhớ

Các hàm truy nhập theo địa chỉ phân đoạn

a Hàm pokeb: Gửi một ký tự vào bộ nhớ

+ Nguyên mẫu trong dos.h như sau:

void pokeb(unsigned seg, unsigned off, char value);

+ Công dụng: Gửi giá trị ký tự value vào bộ nhớ tại địa chỉ phân đoạn seg:off

b Hàm peekb: Nhận một ký tự từ bộ nhớ

+ Nguyên mẫu trong dos.h như sau:

char peekb(unsigned seg, unsigned off);

+ Công dụng: Nhận một byte tại địa chỉ phân đoạn seg:off

c Hàm poke: Gửi một số nguyên vào bộ nhớ

+ Nguyên mẫu trong dos.h như sau:

void poke(unsigned seg, unsigned off, int value);

+ Công dụng: Gửi giá trị nguyên value vào bộ nhớ tại địa chỉ phân đoạn seg:off

d Hàm peek: Nhận một số nguyên từ bộ nhớ

+Nguyên mẫu trong dos.h như sau:

int peek(unsigned seg, unsigned off);

+ Công dụng: Nhận một word tại địa chỉ phõn đoạn seg:off

e Hàm movedata: Sao các byte

+ Nguyên mẫu trong mem.h như sau:

Trang 5

void movedata(unsigned seg_gui, unsigned off_gui,

unsigned seg_nhan, unsigned off_nhan, int n);

+ Công dụng: Sao n byte từ seg_gui:off_gui đến

seg_nhan:off_nhan

Bộ nhớ màn hình văn bản

a Cách biểu diễn ký tự trong bộ nhớ màn hình

Bộ nhớ màn hình văn bản bắt đầu từ địa chỉ :

(0xb800:0x0000)

Khi đưa một ký tự vào vùng nhớ màn hình, thỡ nó sẽ hiện lên màn hình Mỗi ký

tự trên màn hình chiếm 2 byte trong bộ nhớ màn hình: byte đầu chứa mã ASCII, bytethứ hai biểu diễn mầu hiển thị gọi là byte thuộc tính Các bit của byte thuộc tính:

+ Nhóm 3 gồm các bit B3, B2, B1 và B0 Các bit này chứa được một số nguyên

từ 0 đến 15 và biểu thị 16 mầu của ký tự

b Trang màn hình

Mỗi trang màn hình gồm 80x25 ký tự, do đó cần 80x25x2=4000 byte bộ nhớ.Thực tế mỗi trang màn hình được phân bố 4096 = 0x1000 byte Như vậy 4 trang mànhình được phân bố như sau:

+ Trang màn hình thứ 0 bắt đầu từ địa chỉ 0xB800:0x0000

+ Trang màn hình thứ 1 bắt đầu từ địa chỉ 0xB800:0x1000

+ Trang màn hình thứ 2 bắt đầu từ địa chỉ 0xB800:0x2000

+ Trang màn hình thứ 3 bắt đầu từ địa chỉ 0xB800:0x3000

c Chọn trang hiển thị

Tại mỗi thời điểm chỉ có thể hiển thị được một trong 4 trang màn hình Để hiển thị trang màn hình thứ t (t=0,1,2,3) chúng ta sử dụng chức năng 5 của ngắt 0x10 theo mẫu sau:

Trang 6

union REGS v,r;

v.h.ah = 5 ; // Chức năng 5

v.h.al = t ; // Số hiệu trang màn hình cần hiển thị

int86(0x10, &v, &r); // Thực hiện ngắt 0x10

Chuyển đổi địa chỉ

a Để chuyển từ địa chỉ thực sang địa chỉ phân đoạn ta dùng các macro:

unsigned FP_SEG(địa_chỉ_thực)

unsigned FP_OFF(địa_chỉ_thực)

b Để chuyển từ địa chỉ phân đoạn sang địa chỉ thực ta dựng macro:

void far *MK_FP(seg,off)

Ví dụ 1 Sau khi thực hiện các câu lệnh:

char buf[100];

unsigned ds,dx;

ds = FP_SEG(buf); dx = FP_OFF(buf);

thì ds:dx chứa địa chỉ của mảng buf

Ví dụ 2 Sau khi thực hiện các câu lệnh:

char far *pchar;

pchar = (char far*)MK_FP(0xb800:0);

thì pchar trỏ tới địa chỉ đầu của bộ nhớ màn hình Khi đó ta có thể sử dụng các lệnh gán để truy nhập trực tiếp tới bộ nhớ màn hình

3 Cách sử dụng hàm thành viên để đọc/ghi đối tượng ra tệp

Cách khai báo một thành viên là hàm trong một lớp có thể dùng hai dạng chính sau:

+ Mô tả trực tiếp trong định nghiã của lớp mà hàm là thành viên

Trang 7

[virtual] int

+ Mô tả sau bên ngoài sau định nghĩa của lớp mà hàm là thành viên

Hàm thành viên có chức năng điều hành và chức năng khai báo là thành viên được công nhận hiển nhiên của một lớp Chúng ta có thể khai báo một hàm thành viên ở trạngthái tĩnh, gọi là hàm thành viên tĩnh Một hàm thành viên không được khai báo tĩnh thì được gọi là một hàm thành viên (nonstatic)

Giả sử bạn tạo một đối tượng có tên là X của một lớp A có một hàm thành viên là F( ) Nếu bạn gọi hàm XF( ) thì từ khóa trong thân hàm F( ) là địa chỉ của X

Định nghĩa hàm thành viên trong phạm vi bao quanh lớp Phần thân của hàm thànhviên được phân tích sau khi khai báo lớp để các thành viên của lớp có thể được sử dụng trong phần thân của hàm thành viên Ngay cả khi, nếu định nghĩ các chức năng của thành viên xuất hiện trước khi khai báo rằng thành viên trong danh sách thành viên lớp Khi hàm add( ) được gọi trong ví dụ sau đây Các biến dữ liệu a, b, c có thể sử dụng trong phần thân của add( )

Trang 8

4 Cách sử dụng hàm thành viên tĩnh để đọc/ghi nhiều đối tượng của cùng một lớp ra tệp

Hàm thành viên tĩnh được viết theo một trong hai cách:

- Dùng từ khoá static đặt trước định nghĩa hàm thành phần viết bên trong định nghĩa lớp

- Nếu hàm thành phần xây dựng bên ngoài định nghĩa lớp, thì dùng từ khoá static đặt trước khai báo hàm thành phần bên trong định nghĩa lớp Không cho phép dùng từ khoá static đặt trước định nghĩa hàm thành phần viết bên ngoài định nghĩa lớp

Các đặc tính của hàm thành viên tĩnh:

- Hàm thành viên tĩnh là chung cho toàn bộ lớp và không lệ thuộc vào một đối tượng cụthể, nó tồn tại ngay khi lớp chưa có đối tượng nào

- Lời gọi hàm thành viên tĩnh như sau:

Tên lớp :: Tên hàm thành viên tĩnh(các tham số thực sự)

- Vì hàm thành viên tĩnh là độc lập với các đối tượng, nên không thể dùng hàm thành viên tĩnh để xử lý dữ liệu của các đối tượng trong lời gọi phương thức tĩnh Nói cách khác không cho phép truy nhập các thuộc tính (trừ thuộc tính tĩnh) trong thân hàm thành viên tĩnh Đoạn chương trình sau minh họa điều này:

Trang 9

cout << ”\n” << tstienban;

cout <<”\n”<< tenhang //loi

cout <<”\n” << tienban; //loi

static int n; //n la bien tinh

public: void set_m(void) { m= ++n;}

Trang 10

Doi tuong thu : 2

Doi tuong thu : 3

Doi tuong thu : 4

5 Kỹ thuật đọc/ghi các đối tượng của các lớp khác nhau ra cùng một tệp

C++ cung cấp 4 dòng tin chuẩn để làm việc với bàn phím và màn hình Muốn nhập xuất 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 cụ thể C++ cung cấp 3 lớp sream để làm điều này, đó là các lớp:

Ofstream dùng để tạo các dòng xuất (ghi tệp)

Ifstream dùng để tạo các dòng nhập (đọc tệp)

Ftream dùng để tạo các dòng nhập, dòng xuất hoặc dòng nhập/xuất

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

+ Dùng lớp oftream để tạo một dòng xuất và gắn nó với một cụ thể Khi đó việc xuất

dữ liệu ra dòng này cũng đồng nghĩa với việc ghi dữ liệu lên tệp

+ Thực hiện xuất dữ liệu ra dòng xuất vừa tạo như thể xuất dữ liệu ra dòng chuẩn cout

Lớp ofstream thừa kế các phương thức của các lớp ios và ostream Nó cũng kế thừa phương thức:

Close

Của lớp ftreambase

Trang 11

II Code chương trình:

Đề bài: Chương trình quản lý nhân sự của một trường đại học Có 3 loại nhân sự

với các thông tin như sau: Cán bộ quản lý có họ tên, ngày sinh, chức vụ; Giáo viên có

họ tên, ngày sinh, các môn học giảng dạy; Nhân viên phục vụ có họ tên, ngày sinh Trong chương trình có cài đặt hàm thành viên đọc/ghi đối tượng ra tệp, hàm thành viên tĩnh đọc/ghi tất cả các đối tượng nhân sự ra cùng một tệp

static mang hoten; //du lieu tinh khong co kieu chuoi ki tu

static mang ngaysinh; //nen phai dinh nghia lai kieu chuoi ki tu

static int vt1;

static int vt2;

public:

virtual void getData();

virtual void readFile(const char *FileName);

virtual void writeFile(const char *FileName);

static void SreadFile(const char *FileName); //khai bao ham thanh vien tinh

static void SwriteFile(const char *FileName);

Trang 12

class cbql:public nhansu

void readFile(const char *FileName);

void writeFile(const char *FileName);

static void SreadFile(const char *FileName);

static void SwriteFile(const char *FileName);

};

mang cbql::chucvu={""};//khoi tao bien tinh sau khi lop chua no da dinh nghia

class gv:public nhansu

void readFile(const char *FileName);

void writeFile(const char *FileName);

static void SreadFile(const char *FileName);

static void SwriteFile(const char *FileName);};

Trang 13

int chon;

do

{

cout<<endl<<endl;

cout<<"\t\tCHUONG TRINH QUAN LY NHAN SU\n";

cout<<"\t\n 1 Su dung ham thanh vien doc/ghi tep\n";

cout<<"\t\n 2 Su dung ham thanh vien tinh doc/ghi tep\n";

cout<<"\t\n 3 Ket thuc\n";

cout<<"\t\t Su dung ham thanh vien doc/ghi tep\n\n";

cout<<"\t Nhap so luong nhan su: ";cin>>n;cin.ignore();

Trang 15

int i,j=0,n,l=0,k=0;

nhansu p1[50];

cbql p3[50];

cout<<"\t Su dung ham thanh vien tinh doc/ghi tep\n\n";

cout<<"\t Nhap so luong nhan su: ";cin>>n;cin.ignore();

Trang 17

void nhansu::writeFile(const char *FileName)

Trang 18

f.close();

Trang 20

ifstream f;

f.open(FileName,ios::in|ios::binary); f.seekg(nhansu::vt1);

f.read((char*)monday.m,15);

nhansu::vt1=f.tellg();

cout.width(15);cout<<monday.m; f.close();

Ngày đăng: 14/04/2015, 09:00

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w