Sorting Of Objects for the Given Class

compiler is neutron turbo c++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <fstream.h>
#include <conio.h>
#include <stdio.h>
#include <process.h>

class BILL
{
	private:
		int sub_no;
		char sub_name[80];
		int unit;
		char category;
		float slab[5];
		float amount;
		void dcalc(int unit);	
		void ccalc(int unit);		
		void slabcalc(int unit);		
	public:
		int get_sub_no(){return sub_no;}
		char get_category(){return category;}
		void get_sub_det();
		void cdisp();
		void disp(char c);
};

void Sort()
{
	ifstrem fin("CONSUMER.DAT",ios::binary);
	ofstream fout("temp.DAT",ios::binary);
	//I need this function to sort all the objects in the file(already existing) and store it in temp.Dat
	//Help me with this part of code;
}
Last edited on
comparing things
If you want to sort something, you must be able to compare two of them.

Write a function:

1
2
3
4
bool is_BILL_A_less_than_B_by_amount( const BILL& a, const BILL& b )
{
  return a.amount < b.amount;
}

Now you can use std::sort():

1
2
std::deque <BILL> bills;
std::sort( bills.begin(), bills.end(), is_BILL_A_less_than_B_by_amount );

You can even use an inline lambda (instead of having to make a separate function):

1
2
3
4
std::sort( bills.begin(), bills.end(), []( const BILL& a, const BILL& b ) -> bool
{
  return a.amount < b.amount;
} );

If the function is the most common way you'd want to sort a bill, you can make it the default less-than comparison operator:

1
2
3
4
bool operator < ( const BILL& a, const BILL& b )
{
  return a.amount < b.amount;
}

Then you would only have to provide a comparison function to std::sort() if you are sorting with some different criterion:
1
2
// Sort by amount
std::sort( bills.begin(), bills.end() );
1
2
3
4
5
// Sort by category
std::sort( bills.begin(), bills.end(), []( const BILL& a, const BILL& b ) -> bool
{
  return a.category < b.category;
} );


std::deque
By the way, you'll have noticed that the bills are in a std::deque. Load all the bills from file into a std::deque (or std::vector), then sort them, then write them back to file.

It helps if you have a function to read a bill from file. And for that, you need to have a file format. Here's an easy CSV file format:

99, sub_name, 99, C, 1.0, 2.0, 3.0, 4.0, 5.0, 99.99

Input functions are always a little scary looking, because they have to deal with mistakes in the input data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Read a CSV BILL record
std::istream& operator >> ( std::istream& ins, BILL& bill )
{
  // read a line (the entire record)
  std::string s;
  std::getline( ins, s );
  std::istringstream ss( s );

  // makes sure that a comma comes next
  auto comma = [ &ss, &ins ]() -> void
  {
    ss >> std::ws;
    if (ss.peek() != ',') ins.setstate( std::ios::failbit );
  };

  // read the BILL fields
  ss >> bill.sub_no;  comma();                           // [spaces] int [spaces] ','
  ss >> std::ws;  ss.getline( bill.sub_name, 88, ',' );  // [spaces] text ','
  ss >> bill.unit;  comma();                             // [spaces] int [spaces] ','
  ss >> std::ws >> bill.c;  comma();                     // [spaces] char [spaces] ','
  for (unsigned n = 0; n < 5; n++)
    { ss >> bill.slab[n];  comma(); }                    // [spaces] float [spaces] ','  (*5)
  ss >> bill.amount >> std::ws;                          // [spaces] float [spaces] [end]

  // If something went wrong above (we haven't reached the end of the line), 
  // then set the input stream to a fail state
  if (!ss.eof()) ins.setstate( std::ios::failbit );

  return ins;
}

You'll also want an insertion operator to write a bill to file:

1
2
3
4
5
6
7
8
9
10
11
12
// Write a CSV BILL record
std::ostream& operator << ( std::ostream& outs, const BILL& bill )
{
  outs << bill.sub_no   << ", ";
  outs << bill.sub_name << ", ";
  outs << bill.unit     << ", ";
  outs << bill.category << ", ";
  for (unsigned n = 0; n < 5; n++)
    outs << bill.slab[n] << ", ";
  outs << bill.amount   << std::endl;
  return outs;
}

Now life is easy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::deque <BILL> bills;

// Read all bills from file
{
  std::ifstream fin( "CONSUMER.DAT" );
  BILL bill;
  while (fin >> bill)
    bills.push_back( bill );
}

std::sort( bills.begin(), bills.end() );

// Write bills to file
{
  std::ofstream fout( "temp.DAT" );
  for (const auto& bill : bills)
    fout << bill;
}


important points
Compare two things with a custom function.
Use that function to sort lists of things.

When manipulating files:
1 - load the entire file into memory (in a std::deque),
2 - do stuff to it in memory,
3 - then write everything back out to file.

Hope this helps.

Caveat: I typed all this in off the top of my head. (So I may have a typo in there.)
thank you Duoas

but i just wanted the function to compare sub_no

and sorry that im using c++2003 (school oriented program)
and compiler is turbo c++

ill Pm you the entire code so as to facilitate you to help me !!!
What about this ?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void sort()
{
	BILL a;
	int x[100];
	int *p=x;
	int count=0;
	ifstream fin("CONSUMER.DAT",ios::binary);
	ofstream fout("REPORT.DAT",ios::binary);
	fin.seekg(0);
	while(fin.read((char*)&a,sizeof(a)))
	{
		count++;
		*p=a.get_sub_no();
		p++;             //           <-------------there is a problem here
	}
	int temp,pos,small;
	for(int i=0;i<(count-1);i++)
	{
		small=x[i];
		pos=i;
		for(int j=i+1;j<count;j++)
		{
			if(x[j]<small)
			{
				small=x[j];
				pos=j;
			}
		}
		temp=x[i];
		x[i]=x[pos];
		x[pos]=temp;
	}
	fin.seekg(0);
	for(i=0;i<count;i++)
	{
		while(fin.read((char*)&a,sizeof(a)))
		{
			if(x[i]==a.get_sub_no())
				fout.write((char*)&a,sizeof(a));
				break;
		}
	}
	fin.close();
	fout.close();
	cout<<"\nSorting Was Successful !!!";
}


please help me in this part !!!
You shouldn't be reading the file in a sort() function.
Read it first.
Then sort.
Then write.

If you are going to do the binary block things, just read it all at once. Oh, and you have to have an array of the correct thing.

1
2
3
4
5
6
7
8
BILL bills[ 100 ];
int count = 0;
...
fin.read( (char*)bills, sizeof(bills) );

// Now to determine how many BILLs were read.
fin.clear();
count = fin.gpos() / sizeof(BILL);


Now, as for the sorting stuff, you really ought to pay attention to the answers people have taken the time to give you already in this thread.

Hope this helps.
Topic archived. No new replies allowed.