[C++] Đọc ghi file theo dạng nhị phân

Trong ngôn ngữ lập trình C/C++, đọc và ghi file là thực hiện đọc dữ liệu từ file, ghi dữ liệu vào file, cập nhật và xóa dữ liệu. Trong bài viết này, hãy cùng ttnguyen.net khám phá cách sử dụng các hàm trong thư viện chuẩn của C để đọc ghi file trong c/c++.

Xem thêm:

1. Bài toán đọc ghi file trong c

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. Cách lưu file trong c++ dạng nhị phân

  • Khởi tạo một đối tượng ofstream với tên ofs. Đố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 tin ten_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ượng ofs. 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ệnh return.
  • 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ượng ofs. Trước tiên, hàm chuyển đổi số nguyên n 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ức write(). Đâ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ảng n 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ượng ofs.

3. Cách đọc file trong c/c++

  • Khởi tạo một đối tượng ifstream với tên ifs để đọ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ượng ifs.
  • 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ượng ifs.
    • Đầ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.
  • Tiếp theo, tạo một mảng read_numbers có kích thước bằng với read_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ượng ifs.

4. Đọc và ghép dữ liệu từ 2 tệp

– Hàm ghepFile_A_B() thực hiện các bước để ghép mảng trong hai tệp tin A.datB.dat thành một mảng mới và lưu vào tệp tin C.dat.

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.

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.

Ghép 2 file

Sau khi đọc được hai mảng readnumber_nreadnumber_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 đọc ghi file trong c

#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ả đọc ghi file nhị phân c

Lưu file, đọc file dạng nhị phân c++

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:

Nguyễn Tiến Trường

Mình viết về những điều nhỏ nhặt trong cuộc sống, Viết về câu chuyện những ngày không có em