Làm thế nào để lấy giá trị từ file ra

Em đinh thống kê số sinh viên theo tổng điểm sum mà không biết làm sao lấy giá trị tổng điểm của từng sinh viên ra được??

//Student.cpp

 #include "Student.h"
 #include "Point.h"

Student::Student(){
	
}
void Student::setId(string ID) {
	id = ID;
}
string Student::getId() {
	return id;
}
void Student::setName(string NAME) {
	name = NAME;
}
string Student::getName() {
	return name;
}
void Student::setAddress(string ADDRESS) {
	address = ADDRESS;
}
string Student::getAddress() {
	return address;
}
void Student::setSex(string SEX) {
	sex = SEX;
}
string Student::getSex() {
	return sex;
}

void Student::setPoint(Point POINT) {
	point = POINT;
}
Point Student::getPoint() {
	return point;
}

//Point.cpp

 #include "Point.h"



Point::Point(){
	
}
void Point::setMath(float MATH) {
	math = MATH;
}
float Point::getMath() {
	return math;
}
void Point::setPhysical(float PHYSICAL) {
	physical = PHYSICAL;
}
float Point::getPhysical(){
	return physical;
}
void Point::setChemistry(float CHEMISTRY) {
	chemistry = CHEMISTRY;
}
float Point::getChemistry() {
	return chemistry;
}
float Point::getSum() {
	return (math + physical + chemistry);
}

//Hàm đọc file và viết file

#include "IOFile.h"
#include "Student.h"
#include<fstream>
#include<iostream>
using namespace std;

IOFile::IOFile()
{
}

void IOFile::readFile(string path) {
	fstream file(path, ios::in | ios::app);
	string data;
	string line;
	while (!file.eof()) {
		getline(file, line);
		data = data + line + "\n";
		//file >> student.getId() >> student.getName();
		//cout << student.getId() << student.getName() << endl; ??? Sao dung cach nay ko dc??
	}
	cout << data << endl;//in tu file ra man hinh
	file.close();
}
void IOFile::writeFile(string path, Student &student) {
	ofstream file(path, ios::out | ios::app);
	if (!file) {
		cout << "File khong ton tai" << endl;
	}
	else {
		file<< "\t" << student.getId() << "\t" << student.getName() << "\t" << student.getAddress() << "\t" << student.getSex() <<
			"\t" << student.getMath() << "\t" << student.getPhysical() << "\t" << student.getChemistry()
			<<"\t"<< student.getSum()<<"\n";
	}
	file.close();
}

//Hàm thống kê

#include "StudentController.h"
#include "IOFile.h"
#include "Student.h"
#include "Point.h"
#include<fstream>
#include<iostream>
using namespace std;
StudentController::StudentController()
{
}

void StudentController::statitics(Student &st) {
	int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0;
	ifstream file("sinhvien.txt", ios::in);
	ofstream fs("test.txt", ios::out);
	string line;
	
	while (getline(file,line)) {
		
		sum1++;
		if (st.getSum() < 15) {
			sum2++;
		}else if ((st.getSum() >= 15) && (st.getSum() < 20) ){
			sum3++;
		}else if ((st.getSum() >= 20) && (st.getSum() < 25) ){
			sum4++;
		}else if (st.getSum() >= 25) {
			sum5++;
		}
	}
	cout << "Tong so sinh vien: " << sum1 << endl;
	cout << "So sinh vien co diem <15: " << sum2 << endl;
	cout << "So sinh vien co diem >=15 && <20 : " << sum3 << endl;
	cout << "So sinh vien co diem >=25 : " << sum5 << endl;

}
1 Like

st.getPoint().getSum() chứ nhỉ? :sweat_smile:

1 Like

Vẫn sai bạn ạ. nó không nhận được giá trị của toán, lí, hóa

Bạn đưa full project lên được ko. :slight_smile:

1 Like

https://drive.google.com/file/d/0B8OKSyqoQTyFS2lIZEZTcnJyU1U/view?usp=sharing

Full đây bạn xem dùm mình với. Với cả mình bị cái lỗi nhập điểm toán, lí hóa vào nó không ghi được vào file. Kiểu như không nhận giá trị float ấy

Bạn quên set point cho sv ở cuối hàm nhập thông tin

Thêm dòng này vào cuối hàm nhập thông tin.

sv.setPoint(point)

2 Likes

Cảm ơn bạn mình đã fix được cái đó rồi. Vấn đề tiếp theo là mình đang viết hàm thống kê bạn ạ, nó đòi thống kê theo tổng điểm nhưng chả hiểu sao mình không lấy được thằng tổng điểm ra. hịc

void StudentController::statitics(Student &st) {
	float sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0;
	ifstream file("sinhvien.txt");
	string line;
	while (getline(file, line)) {
		//file >> st.getPoint().getMath();
		sum1++;
		if (st.getPoint().getSum() < 15) {
			sum2++;
		}
		else if ((st.getPoint().getSum() >= 15) && (st.getPoint().getSum() < 20)) {
			sum3++;
		}
		else if ((st.getPoint().getSum() >= 20) && (st.getPoint().getSum() < 25)) {
			sum4++;
		}
		else if (st.getPoint().getSum() >= 25) {
			sum5++;
		}
	}
	
	cout << "Tong so sinh vien: " << sum1 << endl;
	cout << "So sinh vien co diem <15: " << sum2 << endl;
	cout << "So sinh vien co diem >=15 && <20 : " << sum3 << endl;
	cout << "So sinh vien co diem >=25 : " << sum5 << endl;
}

Viết trong cùng 1 file .cpp thì mình viết ngon. Dở cái là giờ phải chia ra header file nên mình lúng túng không biết gọi sao cho đúng :((

nhìn là thấy ngay vấn đề, StudentController::statitics(Student &st) là hàm thống kê sum từ file, nhưng tại sao lại cần truyền vào 1 sinh viên cụ thể và lúc tính sum lại dùng chính đối tượng st này để tính sum, thế thì đâu có phải là sum của tất cả sinh viên đâu mà là tính sum của thằng st này đấy chứ.
Tuy bạn có đoạn đọc file nhưng mình chưa thấy tác dụng gì của nó cả ngoài việc dùng làm điều kiện ngắt vòng lặp

while (getline(file, line)){} // đoạn code gán thuộc tính hoặc tạo 1 Student mới từ file ở đâu
if (st.getPoint().getSum() < 15) { // tại sao chỉ dùng mình thằng st được truyền vào hàm để tính
	sum2++;
}

Cảm ơn bạn đã góp ý cho mình. Mình sẽ sửa lại ngay. Mình có thắc mắc là nếu muốn lấy sum của từng thằng student ra thì thao tác lấy dữ liệu từ file ra nó như nào vậy. Bạn chỉ mình được không?

Mình không biết cấu trúc file của bạn như thế nào, nhưng bạn ghi ra file thế nào thì giờ cứ việc làm ngược lại là xong

file sinhvien.txt của mình chứa thông tin gồm id, tên, tổng điểm. Mình muốn lấy thằng tổng điểm ra rồi check với các điều kiện kia để thống kê bạn ạ

Hàm đọc và viết file của mình đây

#include "IOFile.h"
#include "Student.h"
#include<fstream>
#include<iostream>
using namespace std;

IOFile::IOFile()
{
}

void IOFile::readFile(string path) {
	fstream file(path, ios::in | ios::app);
	string data;
	string line;
	while (!file.eof()) {
		getline(file, line);
		data = data + line + "\n";
	}
	cout << data << endl;//in tu file ra man hinh
	file.close();
}
void IOFile::writeFile(string path, Student &student) {
	ofstream file(path, ios::out | ios::app);
	if (!file) {
		cout << "File khong ton tai" << endl;
	}
	else {
		file << "\t" << student.getId() << "\t" << student.getName() << "\t" << student.getAddress() << "\t   " << student.getSex()<<
			"\t\t" << student.getPoint().getMath() << "\t" << student.getPoint().getPhysical() << "\t" << student.getPoint().getChemistry()
			<<"\t"<< student.getPoint().getSum()<<"\n";
	}
	file.close();
}

Do bạn ghi ra file theo chuỗi, mỗi sv 1 dòng, các thông tin cách nhau bằng dấu tab thì để đọc lại bạn cũng đọc từng dòng và cắt chuỗi ra rồi lấy thông tin tại vị trí tương ứng thôi

Bạn demo cho mình với được không? sử dụng getline(file, line) là để đọc từng dòng rồi nhưng tách chuỗi mình chưa nắm được.

Thay vì dùng getline bạn có thể dùng hàm fscanf của C để nhập input theo format dễ hơn.

1 Like

Ủa C++ cũng dùng được fscanf hả bạn???

Được chứ bạn :smiley:

Và để get tên thì bạn dùng format sau
%[^\t] (có nghĩa là nhập tới khi gặp tab thì dừng)

demo: http://ideone.com/Pc03YM

1 Like

Oke. mình sẽ tìm hiểu. Còn đoạn tách chuỗi bạn cho mình ý tưởng được không? :slight_smile:

Tách chuỗi bạn Google ra nhiều mà. :smile:
Còn ko thì bạn có thể tìm hiểu cách dùng hàm strtok bên C.

http://stackoverflow.com/questions/236129/split-a-string-in-c
https://www.safaribooksonline.com/library/view/c-cookbook/0596007612/ch04s07.html

Còn nếu bạn thích ý tưởng thì như thế này:

1/ Nhận đầu vào của hàm tách chuỗi là 1 chuỗi và chuỗi gồm những ký tự cần tách (giả sử là str và delim)
2/ Tạo 1 chuỗi rỗng. (giả sử là tmp)
3/ Duyệt từng ký tự trong str, nếu ký tự đó ko nằm trong chuỗi delim thì ghép ký tự đó với tmp.
4/ Nếu ký tự trong delim thì ko thêm vào tmp, mà đưa vào mảng và khởi tạo tmp = rỗng trở lại
5/ Lặp lại tới khi hết chuỗi str
1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?