Đọc và ghi file là thao tác cơ bản trong lập trình C++ để quản lý dữ liệu như lưu trữ, cập nhật hoặc truy xuất thông tin từ file. Trong bài viết này, TTnguyen sẽ hướng dẫn cách thực hiện đọc và ghi file nhị phân c++ một cách khoa học và dễ hiểu.
Xem thêm:
1. Mô tả yêu cầu bài toán
Bài 39 (TH-CSLT-01). Viết chương trình bao gồm các chương trình con sau:
– Nhập một mảng số nguyên gồm n (n nhập từ bàn phím) phần tử.
– Lưu file (theo dạng nhị phân), nếu tệp chưa tồn tại thì tạo tệp mới, ngược lại, chèn toàn bộ mảng tệp.
– Đọc dữ liệu trong tệp ra một mảng số nguyên ra màn hình
– Sắp xếp theo chiều giảm dần các giá trị trong A, lưu A vào tệp “A.dat”
+ Thực hiện tương tự như vậy và lưu vào tệp “B.dat” với mảng B gồm m phần tử.
+ Thực hiện đọc dữ liệu từ 02 tệp trên và ghép các dữ liệu đọc được vào tệp “C.dat”. Các dữ liệu trong tệp “C.dat” vẫn phải được đảm bảo theo trật tự giảm dần.
2. Lưu file nhị phân C++
Để lưu mảng số nguyên dưới dạng nhị phân, thực hiện như sau:
- Khởi tạo đối tượng
ofstream
:- Sử dụng chế độ
ios::binary
để đảm bảo dữ liệu được ghi theo dạng nhị phân.
- Sử dụng chế độ
- Ghi dữ liệu:
- Ghi số phần tử của mảng.
- Ghi toàn bộ giá trị mảng sử dụng phương thức
write()
.
void luuFile(int a[], int n, string ten_tep) { ofstream ofs; //mo tep ofs.open(ten_tep, ios::binary); //kiem tra if (!ofs.is_open()) { cout << "Khong mo duoc tep!" << endl; return; } ofs.write((char * ) & n, sizeof(int)); // ghi n ofs.write((char * ) & a[0], n * sizeof(int)); // ghi cac phan tu cua mang ofs.close(); }
Giải thích:
- Khởi tạo một đối tượng
ofstream
với tênofs
. Đối tượng này được sử dụng để ghi dữ liệu vào tệp tin. Hàm tiếp tục bằng việc mở tệp tinten_tep
với chế độios::binary
, có nghĩa là tệp tin được mở để thực hiện các thao tác nhị phân. - Tiếp theo, hàm kiểm tra xem tệp tin đã được mở thành công hay chưa bằng cách sử dụng phương thức
is_open()
của đối tượngofs
. Nếu tệp tin không mở được, in ra thông báo lỗi và kết thúc hàm bằng câu lệnhreturn
. - Nếu tệp tin mở thành công, hàm sẽ ghi số phần tử của mảng vào tệp tin bằng cách sử dụng phương thức
write()
của đối tượngofs
. Trước tiên, hàm chuyển đổi số nguyênn
sang một con trỏ kiểu char bằng cách ép kiểu(char*)&n
, sau đó ghi giá trị này vào tệp tin bằng phương thứcwrite()
. Đây là cách ghi dữ liệu nhị phân vào tệp tin. - Tiếp theo, ghi các phần tử của mảng
a
vào tệp tin bằng cách ép kiểu(char*)&a[0]
, và sử dụng kích thước mảngn
nhân với kích thước của kiểu dữ liệu số nguyên để ghi toàn bộ mảng vào tệp tin. - Cuối cùng, hàm đóng tệp tin bằng phương thức
close()
của đối tượngofs
.
3. Đọc file nhị phân trong C++
Các bước thực hiện:
- Khởi tạo
ifstream
: Mở file với chế độ nhị phân. - Đọc dữ liệu:
- Đọc số phần tử từ file.
- Đọc các giá trị mảng.
- Đóng file sau khi đọc.
void docFile(int a[], int n, string ten_tep) { ifstream ifs; //mo file ifs.open(ten_tep, ios::binary); //kiem tra file if (!ifs.is_open()) { cout << "Khong mo duoc file!" << endl; return; } int read_n; ifs.read((char * ) & read_n, sizeof(int)); // doc so phan tu int read_numbers[read_n]; ifs.read((char * ) & read_numbers, sizeof(int) * read_n); // doc cac phan tu // in cac phan tu ra man hinh for (int i = 0; i < read_n; i++) { cout << read_numbers[i] << " "; } cout << endl; ifs.close(); cout << " Doc file thanh cong!" << endl; }
Giải thích:
- Khởi tạo một đối tượng
ifstream
với tênifs
để đọc dữ liệu từ tệp tin. - Tiếp theo, hàm kiểm tra xem tệp tin đã được mở thành công hay chưa bằng cách sử dụng phương thức
is_open()
của đối tượngifs
. - Nếu tệp tin mở thành công, hàm sẽ đọc số phần tử của mảng từ tệp tin bằng cách sử dụng phương thức
read()
của đối tượngifs
.- Đầu tiên, tạo một biến
read_n
để lưu số phần tử của mảng được đọc từ tệp tin. Hàm chuyển đổi số nguyên đó sang một con trỏ kiểu char bằng cách ép kiểu(char*)&read_n
. - Sau đó sử dụng phương thức
read()
để đọc giá trị này từ tệp tin.
- Đầu tiên, tạo một biến
- Tiếp theo, tạo một mảng
read_numbers
có kích thước bằng vớiread_n
để lưu các phần tử của mảng được đọc từ tệp tin. - In các phần tử trong tệp ra màn hình.
- Cuối cùng, sau khi đọc xong toàn bộ mảng từ tệp tin, hàm đóng tệp tin bằng phương thức
close()
của đối tượngifs
.
4. Kết hợp dữ liệu từ hai file nhị phân
– Hàm ghepFile_A_B()
thực hiện các bước để ghép mảng trong hai tệp tin A.dat
và B.dat
thành một mảng mới và lưu vào tệp tin C.dat
.
Để ghép dữ liệu từ hai file A.dat
và B.dat
vào file C.dat
:
- Đọc dữ liệu từ cả hai file.
- Kết hợp mảng từ hai file.
- Sắp xếp mảng kết quả giảm dần.
- Ghi dữ liệu vào file
C.dat
4.1. Mở tệp tin A.dat
– Trước hết, hàm mở tệp tin A.dat
bằng đối tượng ifs
và kiểm tra xem việc mở tệp có thành công hay không. Nếu không thành công thì hàm sẽ in ra thông báo và kết thúc. Sau đó, hàm đọc giá trị n
đầu tiên từ tệp tin A.dat
bằng phương thức read()
, và sau đó đọc toàn bộ mảng readnumber_n
gồm n
phần tử từ tệp tin A.dat
.
4.2. Mở tệp tin B.dat
– Tiếp theo, hàm mở tệp tin B.dat
và kiểm tra việc mở tệp có thành công hay không. Nếu không thành công thì hàm sẽ in ra thông báo và kết thúc. Sau đó, hàm đọc giá trị m
đầu tiên từ tệp tin B.dat
bằng phương thức read()
, và sau đó đọc toàn bộ mảng readnumber_m
gồm m
phần tử từ tệp tin B.dat
.
4.3. Ghép 2 file
Sau khi đọc được hai mảng readnumber_n
và readnumber_m
, hàm tiến hành ghép chúng lại thành một mảng mới readnumber_n
bằng cách duyệt qua từng phần tử của mảng readnumber_m
và thêm chúng vào sau mảng readnumber_n
.
Tiếp theo, hàm sắp xếp mảng readnumber_n
theo thứ tự giảm dần bằng cách gọi hàm sapXep_giamdan()
, sau đó lưu mảng readnumber_n
vào tệp tin C.dat
bằng cách gọi hàm luuFile()
. Hàm tiếp tục in ra các phần tử của mảng readnumber_n
sau khi đã ghép và sắp xếp xong, kết thúc bằng cách đóng tệp tin ifs
.
5. Code mẫu hoàn chỉnh
#include <iostream> #include <fstream> using namespace std; void nhap_mang(int a[], int &n) { cout << "Nhap so phan tu cua mang: "; cin >> n; for (int i = 0; i < n; i++) { cout << "Nhap phan tu thu " << i + 1 << ": "; cin >> a[i]; } } void luuFile(int a[], int n, string ten_tep) { ofstream ofs; //mo tep ofs.open(ten_tep, ios::binary); //kiem tra if(!ofs.is_open()){ cout<<"Khong mo duoc tep!"<<endl; return; } ofs.write((char*)&n, sizeof(int)); // ghi n ofs.write((char*)&a[0], n * sizeof(int)); // ghi cac phan tu cua mang ofs.close(); } void docFile(int a[], int n, string ten_tep){ ifstream ifs; //mo file ifs.open(ten_tep, ios::binary); //kiem tra file if(!ifs.is_open()){ cout<<"Khong mo duoc file!"<<endl; return; } int read_n; ifs.read((char*)&read_n, sizeof(int)); // doc so phan tu int read_numbers[read_n]; ifs.read((char*)&read_numbers, sizeof(int)*read_n);// doc cac phan tu // in cac phan tu ra man hinh for(int i=0;i<read_n;i++){ cout<<read_numbers[i]<<" "; } cout<<endl; ifs.close(); cout<<" Doc file thanh cong!"<<endl; } void xuat_mang(int a[], int n) { for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << endl; } void sapXep_giamdan(int a[], int n){ for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ if(a[i]<a[j]){ int tg=a[i]; a[i]=a[j]; a[j]=tg; } } } } // Doc du lieu tu 2 tep A.dat va B.dat void ghepFile_A_B(){ ifstream ifs; // doc file A ifs.open("A.dat", ios::binary); if(!ifs.is_open()){ cout<<"Khong mo duoc tep!"<<endl; return; } int read_n; ifs.read((char*)&read_n, sizeof(int)); int readnumber_n[read_n]; ifs.read((char*)&readnumber_n, read_n*sizeof(int)); ifs.close(); // doc file b ifs.open("B.dat", ios::binary); if(!ifs.is_open()){ cout<<"Khong mo duoc tep!"<<endl; return; } int read_m; ifs.read((char*)&read_m, sizeof(int)); int readnumber_m[read_m]; ifs.read((char*)&readnumber_m, read_m*sizeof(int)); //ghep mang for(int i=0;i<read_m;i++){ readnumber_n[read_n+i]=readnumber_m[i]; } // sap xep sapXep_giamdan(readnumber_n,read_m+read_n); //Luu file luuFile(readnumber_n,read_m+read_n,"C.dat"); // Xuat mang cout<<" Mang C: "; for(int i=0;i<read_m+read_n;i++){ cout<<readnumber_n[i]<<" "; } cout<<endl; ifs.close(); } int main() { int chon; int a[255],n,b[255],m; do{ cout<<" |1. Nhap mang A"<<endl; cout<<" |2. Nhap mang B"<<endl; cout<<" |3. Sap xep va luu file mang A"<<endl; cout<<" |4. Sap xep va luu file mang B"<<endl; cout<<" |5. Doc file mang A"<<endl; cout<<" |6. Doc file mang B"<<endl; cout<<" |7. Xuat mang C"<<endl; cout<<" |0. Thoat"<<endl; cout<<"Lua chon: "; cin>>chon; switch(chon){ case 1: { nhap_mang(a,n); cout<<" Mang A: "; xuat_mang(a,n); break; } case 2: { nhap_mang(b,m); cout<<" Mang B: "; xuat_mang(b,m); break; } case 3: { sapXep_giamdan(a,n); luuFile(a,n, "A.dat"); break; } case 4: { sapXep_giamdan(b,m); luuFile(b,m, "B.dat"); break; } case 5: { docFile(a,n,"A.dat"); break; } case 6: { docFile(b,m,"B.dat"); break; } case 7: { // gop mang ghepFile_A_B(); break; } default :break; } }while(chon!=0); return 0; }
4. Kết quả chạy chương trình
Trên đây là đoạn mã đọc ghi file binary trong c. Cảm ơn các bạn đã tham khảo!
Tải full bài tập thực hành lập trình C/C++ có lời giải:
Bài viết cùng chủ đề: