Click here to Skip to main content
15,441,434 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to display student data using his id. the file is structured by length indicator for field and delimiter for record.
my code works only on the first and second student but it doesn't work on the third or the forth student

What I have tried:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
struct student{
	 int id;
	char name[20];
	float gpa;
	char address[50];
};

void add_student(){

	
	student s;
	fstream stud;
	
	stud.open("sd.txt",ios::app);
	while(stud.is_open()){
	short length;
				cout << "enter student ID: "; 
				cin >> s.id;
				cin.ignore();
				cout << "enter student Name: "; 
				cin.getline(s.name,20);
				cout << "enter student GPA: "; 
				cin >> s.gpa;
				cin.ignore();
				cout << "enter student Address: ";
				cin.getline(s.address,50);
				stud.write((char*)(&s.id), sizeof(short));
				stud << s.id; 
				length = strlen(s.name);
				stud.write((char*)(&length), sizeof(short));
				stud.write(s.name, length);
				stud.write((char*)(&s.gpa), sizeof(short));
				stud <<s. gpa;
				length = strlen(s.address);
				stud.write((char*)(&length), sizeof(short));
				stud.write(s.address, length);
				stud << "$";
				stud<<'\n';
				stud.close();

}
	
}


void search(){
	
	student s;
	
		short length;
		int search_id;
		char item;
		cout << "Enter your id to search: ";
		cin >> search_id;
		ifstream myfile;
		myfile.open("sd.txt", ios::binary);
		while(myfile.is_open()){
		while (myfile>>item)
		{
			if (item == search_id) {
				cout << "Student data:" << endl;
				myfile.seekg(-1, ios::cur);
				myfile.read((char*)(&length), sizeof(short));
				myfile >> s.id;
				myfile.read((char*)(&length), sizeof(short));
				myfile.read(s.name, length);
				s.name[length] = '\0';
				myfile.read((char*)(&length), sizeof(short));
				myfile >> s.gpa;
				myfile.read((char*)(&length), sizeof(short));
				myfile.read(s.address, length);
				s.address[length] = '\0';
				cout << "student id: " <<s. id << endl;
				cout << "student name: " << s.name << endl;
				cout << "student gpa: " << s.gpa << endl;
				cout << "student address: " << s.address << endl;
				break;
			}
		}
		myfile.close();
}
}
void display(){

	fstream display;
	display.open("sd.txt");
	while(display.is_open()){
	while(!display.eof())
	{
		string p;
		display>>p;
		
		cout<<p<<endl;
	}

	display.close();

}
}

int main(){
	// please create a txt file called sd first
	int o;
	cout<<"choose if you want to add a student choose 1 -- if you want to search a student by ID choose 2 -- if you want to display all the student choose 3 "<<endl;
	cout<<"your choise is : ";
	cin>>o;
	if(o==1)
		add_student();
	else if (o==2)
		search();
	else if(o==3)
		display();
	else
		cerr<<"error file can't open ..."<<endl;

	system("pause");
}
Posted
Updated 24-Mar-22 5:19am
Comments
jeron1 24-Mar-22 10:42am    
Maybe you could explain what exactly doesn't work, and post a small, testable example of the file data.

You have
C++
stud.write((char *)&s.id, sizeof(short);
stud << s.id;

That writes the student id to the file twice, once as a binary number, and once as an text string. So I don't think your data file ends up with the data you think it does.
You also have a data mismatch here: you're only writing 2 bytes from student::id, not all four. This means if the student ID is greater than 65535, you will only write out the bottom four bytes.

You can simplify things greatly by just writing the student struct as a binary blob
C++
stud.write( (char *)&s, sizeof s);
This will write the entire structure out in one go. No need to write the elements individually.

The search then becomes
C++
student s;
bool found = false;
ifstream stud("sd.txt", ios::binary);
while( !found )
{
    stud.read((char *)&s, sizeof s);
    if( stud.eof() )  // eof bit gets set only after EOF is read from file
      break;

    if(s.id = item)
    {
       // handle found record
       found = true;
    }
}
if( !found )
{
   // handle record not found
}

If you do write your student data as a single binary blob, you don't have issues updating. If you change a name from say, "J. Smith", to "James Smith", in your current schema, you'll have to read in all records after "J. Smith"'s, write out the updated "Jame Smith" record, then write out all the successive student records. As a binary blob, though, all you need to do update the student struct, and write it out in the correct location. The output will always be 80 bytes, regardless of the struct's contents.
 
Share this answer
 
Comments
CPallini 24-Mar-22 11:57am    
5.
Start by looking at the file data, any compare what the first two =lines look like compared to the third. Then use the debugger to look at the code while it is running and find out what your data looks like to the code.

We can't do that - we have no idea what your data looks like!
So, it's going to be up to you.
Fortunately, you have a tool available to you which will help you find out what is going on: the debugger. How you use it depends on your compiler system, but a quick Google for the name of your IDE and "debugger" should give you the info you need.

Put a breakpoint on the first line in the function, and run your code through the debugger. Then look at your code, and at your data and work out what should happen manually. Then single step each line checking that what you expected to happen is exactly what did. When it isn't, that's when you have a problem, and you can back-track (or run it again and look more closely) to find out why.

Sorry, but we can't do that for you - time for you to learn a new (and very, very useful) skill: debugging!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900