30/09/2018, 21:39

Nhập suất file nhị phân, m.n xem hộ em sao em chạy nó lỗi với ạ

#include <iostream>
#include  <string>
#include <fstream>

using namespace std;

 struct SinhVien{
 	string ten;
 	int tuoi;
 	string lop;
 };
 
 
 void NhapTT(SinhVien *sv, int n){
 	ofstream dulieu("OUT.bin");
 	cin.ignore();
 	for(int  i = 0; i < n; i++){
 	cout << "nhap ten : ";
 	getline(cin , (sv +i)->ten);
 	cout << "nhap tuoi : ";
 	cin  >> (sv+i)->tuoi;
 	cin.ignore();
 	cout << "nhao lop : ";
 	getline(cin, (sv +i)->lop);
 	cout << endl;
 	
 	dulieu.write((char*) (sv+i), sizeof(SinhVien));
	 }
	 dulieu.close();
 }
 

void XuatTT(SinhVien *sv, int n){
	ifstream dulieu("OUT.bin", ios::binary);
	for(int j =0; j < n; j++){
	dulieu.read((char*) (sv+j), sizeof(SinhVien));
	
	cout << "Ten : " << (sv +j)->ten <<endl;
	cout << "lop : " << (sv +j)->lop <<endl;
	cout << "tuoi : " << (sv +j)->tuoi <<endl <<endl;
	}
}

int main(){
	int n;
	cout << "nhap so luong sinh vien : ";
	cin >> n;
	SinhVien *sv = new SinhVien[n];
	NhapTT(sv, n);
	XuatTT(sv , n); 	
}
trần đại hiệp viết 23:50 ngày 30/09/2018

ai giúp em với ạ :3 . Em đang rất cần mà không biết fix kiểu gì luôn ạ.Em cảm ơn

viết 23:47 ngày 30/09/2018

dulieu.write((char*) (sv+i), sizeof(SinhVien));

dulieu.read((char*) (sv+j), sizeof(SinhVien));

Hai dòng này bạn sửa lại lần lượt là:

dulieu.write(reinterpret_cast<char*> (sv+i), sizeof(SinhVien));
dulieu.read(reinterpret_cast<char*> (sv+j), sizeof(SinhVien));
trần đại hiệp viết 23:51 ngày 30/09/2018

vẫn lỗi ạ, lỗi là nó không đọc được file nhị phân ý ạ

viết 23:42 ngày 30/09/2018

Mình chạy ổn mà bạn, báo lỗi như thế nào

trần đại hiệp viết 23:42 ngày 30/09/2018

anh cmt hàm nhập lại và chỉ cho chạy mỗi hàm xuất ra thôi, vì trong hàm xuất có lệnh đọc file nên phải xuất được ra dữ liệu nhưng khi em cmt hàm nhập thì nó lại ko in ra gì và báo lỗi

trần đại hiệp viết 23:42 ngày 30/09/2018

viết 23:44 ngày 30/09/2018

Do trong struct của bạn có đối tượng kiểu string, trong string chứa nhiều thông tin như con trỏ nội bộ (internal) trỏ vào các ký tự, kích thước,… nhưng lúc ghi thì chỉ con trỏ được ghi lên file. Thực tế thì dữ liệu ký tự sẽ không được ghi lên file, khi bạn đọc tập tin, con trỏ string nội bộ sẽ được thiết lập, nhưng bộ nhớ bị deallocated, dẫn đến lỗi segmentation fault, làm chương trình crash. Việc đọc, ghi string khá phức tạp, bạn phải ghi size của string trước, sau đó mới ghi các kí tự, bạn xem ví dụ:

std::string str = "Hello";
std::size_t size = str.size();
file.write(reinterpret_cast<char *>(&size), sizeof(size));
file.write(someString.data(), size);

và để đọc lại thì bạn phải đọc size trước, sau đó dùng phương thức resize để thay đổi kích thước string rồi mới đọc ký tự vào:

std::string str;
std::size_t size;
file.read(reinterpret_cast<char *>(&size), sizeof(size));
str.resize(size);
file.read(&str[0], size);

Còn bài của bạn, để đơn giản mình sửa lại 1 chút ở phần struct, từ string thành mảng char:

#include <iostream>
#include  <string>
#include <fstream>

using namespace std;

 struct SinhVien{
     //char ten[20];
     char ten[20];
     int tuoi;
     //string lop
     char lop[10];
 };
 
 /*
 void NhapTT(SinhVien *sv, int n){
     ofstream dulieu("OUT.bin");
     cin.ignore();
     for(int  i = 0; i < n; i++){
     cout << "nhap ten : ";
     //getline(cin , (sv +i)->ten);
     cin.getline((sv+i)->ten,20);
     cout << "nhap tuoi : ";
     cin  >> (sv+i)->tuoi;
     cin.ignore();
     cout << "nhao lop : ";
     //getline(cin, (sv +i)->lop);
     cin.getline((sv+i)->lop,10);
     cout << endl;
     
     dulieu.write(reinterpret_cast<char*> (sv+i), sizeof(SinhVien));
     }
     dulieu.close();
 }
*/ 

void XuatTT(SinhVien *sv, int n){
    ifstream dulieu("OUT.bin", ios::binary);
    for(int j =0; j < n; j++){
    dulieu.read(reinterpret_cast<char*> (sv+j), sizeof(SinhVien));
    
    cout << "Ten : " << (sv +j)->ten <<endl;
    cout << "lop : " << (sv +j)->lop <<endl;
    cout << "tuoi : " << (sv +j)->tuoi <<endl <<endl;
    }
}

int main(){
    int n;
    cout << "nhap so luong sinh vien : ";
    cin >> n;
    SinhVien *sv = new SinhVien[n];
    //NhapTT(sv, n);
    XuatTT(sv , n);     
}
trần đại hiệp viết 23:46 ngày 30/09/2018

em đọc được rồi ạ , em cảm ơn anh nhiều nhé ! anh có thể cho em xin nick facebook của anh được không ạ, để đôi khi có gì thắc mắc thì em hỏi anh với ạ
Em cảm ơn anh rất nhiều

Bài liên quan
0