Tải bản đầy đủ (.docx) (8 trang)

Chương 7 Các dòng tập tin (Stream) Ghi dữ liệu lên tệp

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (84.55 KB, 8 trang )

Ghi dữ liệu lên tệp
11.1. Lớp ofstream
Để ghi dữ liệu lên tệp chúng ta sử dụng lớp ofstream. Lớp ofstream thừa kế các phương
thức của các lớp ios và ostream. Nó cũng thừa kế phương thức:
close
của lớp fstreambase. Ngoài ra lớp ofstream có thêm các hàm tạo và các phương thức sau:
1. Hàm tạo:
ofstream() ; // Không đối
dùng để tạo một đối tượng ofstream (dòng xuất), chưa gắn với tệp.
2. Hàm tạo:
ofstream(const char *fn, int mode = ios::out,
int prot = filebuf::openprot);dùng để tạo một đối tượng ofstream, mở tệp có
tên fn để ghi và gắn đối tượng vừa tạo với tệp được mở.
+ Tham số fn cho biết tên tệp.
+ Tham số mode có giá trị mặc định là ios::out (mở để ghi). Tham số này có thể là một hợp
của các giá trị sau:
ios::binary ghi theo kiểu nhị phân (mặc định theo kiểu văn bản)
ios::out ghi tệp, nếu tệp đã có thì nó bị xoá
ios::app ghi bổ sung vào cuối tệp
ios::ate chuyển con trỏ tệp tới cuối tệp sau khi mở tệp
ios::trunc xoá nội dung của tệp nếu nó tồn tại
ios::nocreate nếu tệp chưa có thì không làm gì (bỏ qua)
ios::noreplace nếu tệp đã có thì không làm gì (bỏ qua)
+ Tham số thứ ba prot quy định cấp bảo vệ của dòng tin, tham số này có thể bỏ qua vì nó đã
được gán một giá trị mặc định.
3. Hàm tạo:
ofstream(int fd);
dùng để tạo một đối tượng ofstream và gắn nó với một tệp có chỉ số fd đang mở.
(Để mở và lấy chỉ số (số hiệu) tệp có thể dùng hàm _open, xem cuốn Kỹ thuật Lập trình C
của tác giả).
4. Hàm tạo:


ofstream(int fd, char *buf, int n);
dùng để tạo một đối tượng ofstream , gắn nó với một tệp có chỉ số fd đang mở và sử dùng một
vùng nhớ n byte do buf trỏ tới làm bộ đệm.
5. Phương thức:
void open(const char *fn, int mode = ios::out,
int prot = filebuf::openprot);dùng để mở tệp có tên fn để ghi và gắn nó với
đối tượng ofstream. Các tham số của phương thức có cùng ý nghĩa như trong hàm tạo thứ 2.
11.2. Các cách ghi tệp
400
Có 2 cách chính sau:
+ Cách 1: Dùng hàm tạo 2 để xây dựng một dòng xuất, mở một tệp để ghi và gắn tệp với
dòng xuất. Sau đó dùng toán tử xuất << và các phương thức để xuất dữ liệu ra dòng xuất vừa
tạo như thể xuất dữ liệu ra cout (xem các mục trên).
+ Cách 2: Dùng hàm tạo 1 để xây dựng một dòng xuất. Sau đó dùng phương thức open để
mở một tệp cụ thể và cho gắn với dòng xuất vừa xây dựng. Khi không cần làm việc với tệp này
nữa, chúng ta có thể dùng phương thức close để chấm dứt mọi ràng buộc giữa dòng xuất và
tệp. Sau đó có thể gắn dòng xuất với tệp khác. Theo cách này, có thể dùng một dòng xuất (đối
tượng ofstream) để xuất dữ liệu lên nhiều tệp khác nhau.
11.3. Ví dụ
Chương trình 1: Chương trình dưới đây sẽ nhập danh sách n thí sinh. Thông tin thí sinh
gồm: Họ tên, tỉnh hoặc thành phố cư trú, số báo danh, các điểm toán lý hoá. Dữ liệu thí sinh
được ghi trên 2 tệp: Tệp DS1.DL ghi thí sinh theo thứ tự nhập từ bàn phím, tệp DS2.DL ghi
thí sinh theo thứ tự giảm của tổng điểm. Cấu trúc của 2 tệp như sau:
Dòng đầu ghi một số nguyên bằng số thí sinh.
Các dòng tiếp theo ghi dữ liệu của thí sinh. Mỗi thí sinh ghi trên 2 dòng, dòng 1 ghi họ tên
trên 24 vị trí và tên tỉnh trên 20 vị trí. Dòng 2 ghi số báo danh (6 vị trí), các điểm toán, lý , hoá
và tổng điểm (mỗi điểm ghi trên 6 vị trí trong đó một vị trí chứa phần phân). Chương trình sử
dụng lớp TS (Thí sinh) có 3 phương thức: Nhập, sắp xếp và ghi tệp. Cách ghi tệp sử dụng ở
đây là cách 1: Dùng hàm tạo dạng 2 của lớp ofstream.
Chương trình 2 ngay bên dưới cũng giải quyết cùng bài toán nêu trên nhưng sử dụng cách

ghi tệp thứ 2 (dùng hàm tạo 1 và phương thức open)
Một điều đáng nói ở đây là việc nhập một chuỗi ký tự (như họ tên và tên tỉnh) bằng các
phương thức get hoặc getline chưa được thuận tiện, vì 2 lý do sau: thứ nhất là các phương thức
này có thể bị ký tự chuyển dòng (còn sót trên cin) làm trôi. Thứ hai là các phương thức này có
thể để lại một số ký tự trên dòng cin (nếu số ký tự gõ nhiều hơn so với quy định) và các ký tự
này sẽ gây ảnh hưởng đến các phép nhập tiếp theo. Để khắc phục các nhược điểm trên, chúng
ta đưa vào 2 chương trình trên hàm getstr để nhập chuỗi ký tự từ bàn phím.
//CT7_10.CPP
// Ghi Tep
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
void getstr(char *str,int n)
{
char tg[21];
while(1) // Bỏ qua Enter và nhập tối đa n-1 ký tự
{
cin.get(str,n);
402
if (str[0])
break;
else
cin.ignore();
}
while(1) // Loại các ký tự còn lại ra khỏi dòng nhập cin
{
cin.get(tg,20);

if (tg[0]==0)
{
cin.ignore();
break;
}
}
}
struct TSINH
{
char ht[25];
char ttinh[21];
int sobd;
float dt,dl,dh,td;
} ;
class TS
{
private:
int sots;
TSINH *ts;
public:
TS()
{
sots=0;
ts = NULL;
}
void nhap();
void sapxep();
void ghitep(char *ttep);
};
void TS::nhap()

{
cout << "\n So thi sinh: " ;
cin >> sots ;
int n=sots;
ts = new TSINH[n+1];
for (int i=1; i<=n; ++i)
{
cout << "\n Nhap thi sinh thu: " << i << endl;
cout << "Ho ten: " ;
getstr(ts[i].ht,25);
cout << "Tinh hoac thanh pho: " ;
getstr(ts[i].ttinh,21);
cout << "So bao danh: " ;
cin >> ts[i].sobd ;
cout << "Cac diem toan, ly, hoa: " ;
cin >> ts[i].dt >> ts[i].dl >> ts[i].dh ;
ts[i].td =ts[i].dt + ts[i].dl + ts[i].dh ;
}
}
void TS::sapxep()
{
int n = sots;
for (int i=1; i< n; ++i)
for (int j=i+1; j<= n; ++j)
if (ts[i].td < ts[j].td)
{
TSINH tg = ts[i];
ts[i] = ts[j];
ts[j] = tg;
}

}
void TS::ghitep(char *ttep)
{
ofstream f(ttep);
f << sots ;
f << setprecision(1) << setiosflags(ios::showpoint);
for (int i=1; i<=sots; ++i)
{
f << endl << setw(24) << ts[i].ht << setw(20) << ts[i].ttinh ;
404
f << endl << setw(6) << ts[i].sobd
<< setw(6) << ts[i].dt
<< setw(6) << ts[i].dl
<< setw(6) << ts[i].dh
<< setw(6) << ts[i].td ;
}
f.close();
}
void main()
{
clrscr();
TS t;
t.nhap();
t.ghitep("DS1.DL");
t.sapxep();
t.ghitep("DS2.DL");
cout << "\n Hoan thanh";
getch();
}
Chương trình 2:

//CT7_11.CPP
// Ghi Tep
#include <iostream.h>
#include <iomanip.h>
#include <fstream.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
void getstr(char *str,int n)
{
char tg[21];
while(1)
{
cin.get(str,n);
if (str[0])
break;
else
cin.ignore();
406

×