Data is Not Being Sorted With Bubble Sort

Hello,
I'm still new to c++, about to finish first freshman semester at college. My Professor has asked us to write a program that takes in sides of a triangle from a file and outputs a formatted file with data about the triangles. He asked us to sort the triangles using bubble sort based on the area that is outputted. I have written the function to implement bubble sort but the output data isn't sorted based on the area of the triangles. Any help is appreciated.
Thanks!
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <fstream>
#include <cstdlib>

using namespace std;

const int MAXSIZE = 100; // define const int for max number of records

class Triangle{
private:
    double side1;
    double side2;
    double side3;
public:
    //setters
    enum triangleType{scalene, isosceles, equilateral};
    void setSide1(double s1){
        if(s1<0) s1 = 0;
        side1 = s1;
    }
    void setSide2(double s2){
        if(s2<0) s2 = 0;
        side2 = s2;
    }
    void setSide3(double s3){
        if(s3<0) s3 = 0;
        side3 = s3;
    }
    //getters
    double getPerimeter(){ // member to find perimeter of triangle
        return side1+side2+side3;
    }
    double getArea(){ // member to find area of triangle
    double area, s;

    s = getPerimeter()/2;
    area = sqrt(s*(s-side1)*(s-side2)*(s-side3));
    return area;
}

string triangleShape(){ //member to determine triangle type
    string answer;
    if ((side1 == side2) && (side2 == side3) && (side1 == side3)){
        answer = "equilateral";
    }
    else if ((side1 == side2) && (side1 != side3) || (side2 == side3) && (side2 != side1) || (side1 == side3) && (side1 != side2)){
        answer = "isosceles";
    }
    else{
        answer = "scalene";
    }
return answer;
}
double largeTri(){ //member to find largest side of triangle
    if ((side1 > side2) && (side1 > side3)){
        return side1;
    }else if((side2>side1)&&(side2>side3)){
        return side2;
    }else{
        return side3;
    }
}

float smallTri(){ //member to find smallest side of triangle
    if ((side1<side2) && (side1<side3)){
        return side1;
    }else if((side2<side1) && (side2<side3)){
        return side2;
    }else{
        return side3;
    }
}
};

void sortT(Triangle tri[], int totalrecords); // prototype function to sort records
void swapRecords(Triangle& tri1, Triangle& tri2); // prototype function to swap records

void drawLine(ofstream &fout, char ch, int length) //function to draw characters on output file
{
    fout << setfill(ch);
    fout << setw(length) << "" << endl;
    fout << setfill(' ');
}
int main(int argc, char* argv[])
{
    Triangle triangles[MAXSIZE];
    int numOfRecords = 0; // keeps track of the amount of records entered
    double side1, side2, side3; // defines variables for each side
    string infile = ""; //initializes string for input file name
    string outfile = ""; //initializes string of output file name

    cout << "Please enter input file name: " << endl;
    cin >> infile; //store user input for file name
    cout << "Please enter output file name: " << endl;
    cin >> outfile; //store user input for file name
        ifstream fin; //declare fin
        ofstream fout; //declare fout

    fin.open(infile);
        if(!fin){ // if file cannot be opened
            cout << "File couldn't be opened, make sure file exists" << endl;
            cin.get();
            exit(1);
        }
    fout.open(outfile);
        if(!fout){ // if write file cannot be created
            cout << "File couldn't be created" << endl;
        }
        drawLine(fout, '*', 92);
        fout << setw(60) << right << "Triangle Information" << endl;
            drawLine(fout, '*', 92);

    fout << setw(3) << right << "#" << setw(10) << right << "side a" << setw(10) << right << "side b" <<
        setw(10) << right << "side c" << setw(10) << right << "area" << setw(12) << right << "perimeter" <<
            setw(15) << right << "type" << setw(10) << right << "max" << setw(10) << right << "min" << endl;

        drawLine(fout, '=', 92);
    //format output file

while(!fin.eof() && (numOfRecords < MAXSIZE)) //loop through records and output to file
{
    fin >> side1 >> side2 >> side3; // read and store data in side variables
        numOfRecords++; //keep track of records
        Triangle t1;
    //set data to sides of triangle
    t1.setSide1(side1);
    t1.setSide2(side2);
    t1.setSide3(side3);

    sortT(triangles, numOfRecords); // calls sort function
    //format output data
        fout << setw(3) << right << numOfRecords;
        fout << fixed;
        fout << setprecision(2);
        fout << setw(10) << right << side1 << setw(10) << right << side2 << setw(10) <<
            right << side3 << setw(10) << right << t1.getArea() << setw(12) << right << t1.getPerimeter() <<
                setw(15) << right << t1.triangleShape() <<
                    setw(10) << right << t1.largeTri() << setw(10) << right << t1.smallTri() << endl;
}
    return 0;
}

void sortT(Triangle tri[], int totalrecords) //function to implement bubble sort
{
    int i, j;
    for(i=0; i < totalrecords; i++)
    {
        for(j=0; j < totalrecords - i - 1; j++)
        {
            if(tri[j].getArea() > tri[j+1].getArea()); // if records aren't in order swap them
            {
                swapRecords(tri[j], tri[j+1]);
            }
        }
    }
}
void swapRecords(Triangle& tri1, Triangle& tri2) //function to swap records
{
    Triangle temp = tri1;
    tri1 = tri2;
    tri2 = temp;
}
First of all, a consistent indentation style helps.
https://en.wikipedia.org/wiki/Indentation_style
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <fstream>
#include <cstdlib>

using namespace std;

const int MAXSIZE = 100;        // define const int for max number of records

class Triangle {
private:
  double side1;
  double side2;
  double side3;
public:
  //setters
  enum triangleType { scalene, isosceles, equilateral };
  void setSide1(double s1) {
    if (s1 < 0)
      s1 = 0;
    side1 = s1;
  } void setSide2(double s2) {
    if (s2 < 0)
      s2 = 0;
    side2 = s2;
  }
  void setSide3(double s3) {
    if (s3 < 0)
      s3 = 0;
    side3 = s3;
  }
  //getters
  double getPerimeter() {       // member to find perimeter of triangle
    return side1 + side2 + side3;
  }
  double getArea() {            // member to find area of triangle
    double area, s;

    s = getPerimeter() / 2;
    area = sqrt(s * (s - side1) * (s - side2) * (s - side3));
    return area;
  }

  string triangleShape() {      //member to determine triangle type
    string answer;
    if ((side1 == side2) && (side2 == side3) && (side1 == side3)) {
      answer = "equilateral";
    } else if ((side1 == side2) && (side1 != side3) || (side2 == side3)
               && (side2 != side1) || (side1 == side3) && (side1 != side2)) {
      answer = "isosceles";
    } else {
      answer = "scalene";
    }
    return answer;
  }
  double largeTri() {           //member to find largest side of triangle
    if ((side1 > side2) && (side1 > side3)) {
      return side1;
    } else if ((side2 > side1) && (side2 > side3)) {
      return side2;
    } else {
      return side3;
    }
  }

  float smallTri() {            //member to find smallest side of triangle
    if ((side1 < side2) && (side1 < side3)) {
      return side1;
    } else if ((side2 < side1) && (side2 < side3)) {
      return side2;
    } else {
      return side3;
    }
  }
};

void sortT(Triangle tri[], int totalrecords); // prototype function to sort records
void swapRecords(Triangle & tri1, Triangle & tri2); // prototype function to swap records

void drawLine(ofstream & fout, char ch, int length) //function to draw characters on output file
{
  fout << setfill(ch);
  fout << setw(length) << "" << endl;
  fout << setfill(' ');
}

int main(int argc, char *argv[])
{
  Triangle triangles[MAXSIZE];
  int numOfRecords = 0;         // keeps track of the amount of records entered
  double side1, side2, side3;   // defines variables for each side
  string infile = "";           //initializes string for input file name
  string outfile = "";          //initializes string of output file name

  cout << "Please enter input file name: " << endl;
  cin >> infile;                //store user input for file name
  cout << "Please enter output file name: " << endl;
  cin >> outfile;               //store user input for file name
  ifstream fin;                 //declare fin
  ofstream fout;                //declare fout

  fin.open(infile);
  if (!fin) {                   // if file cannot be opened
    cout << "File couldn't be opened, make sure file exists" << endl;
    cin.get();
    exit(1);
  }
  fout.open(outfile);
  if (!fout) {                  // if write file cannot be created
    cout << "File couldn't be created" << endl;
  }
  drawLine(fout, '*', 92);
  fout << setw(60) << right << "Triangle Information" << endl;
  drawLine(fout, '*', 92);

  fout << setw(3) << right << "#" << setw(10) << right << "side a" << setw(10)
      << right << "side b" << setw(10) << right << "side c" << setw(10) << right
      << "area" << setw(12) << right << "perimeter" << setw(15) << right <<
      "type" << setw(10) << right << "max" << setw(10) << right << "min" <<
      endl;

  drawLine(fout, '=', 92);
  //format output file

  while (!fin.eof() && (numOfRecords < MAXSIZE))  //loop through records and output to file
  {
    fin >> side1 >> side2 >> side3; // read and store data in side variables
    numOfRecords++;             //keep track of records
    Triangle t1;
    //set data to sides of triangle
    t1.setSide1(side1);
    t1.setSide2(side2);
    t1.setSide3(side3);

    sortT(triangles, numOfRecords); // calls sort function
    //format output data
    fout << setw(3) << right << numOfRecords;
    fout << fixed;
    fout << setprecision(2);
    fout << setw(10) << right << side1 << setw(10) << right << side2 << setw(10)
        << right << side3 << setw(10) << right << t1.
        getArea() << setw(12) << right << t1.
        getPerimeter() << setw(15) << right << t1.
        triangleShape() << setw(10) << right << t1.
        largeTri() << setw(10) << right << t1.smallTri() << endl;
  }
  return 0;
}

void sortT(Triangle tri[], int totalrecords)  //function to implement bubble sort
{
  int i, j;
  for (i = 0; i < totalrecords; i++) {
    for (j = 0; j < totalrecords - i - 1; j++) {
      if (tri[j].getArea() > tri[j + 1].getArea()); // if records aren't in order swap them
      {
        swapRecords(tri[j], tri[j + 1]);
      }
    }
  }
}

void swapRecords(Triangle & tri1, Triangle & tri2)  //function to swap records
{
  Triangle temp = tri1;
  tri1 = tri2;
  tri2 = temp;
}


Now can you see that you're "sorting AND printing" every time you read a triangle in from your file.
Also, you're not even updating the array, it's just "read and print t1".

Try some functions, instead of a "do everything blob".
1
2
3
readFile(fin, triangles, numOfRecords);
sortT(triangles, numOfRecords);
printData(fout, triangles, numOfRecords);


Also, compile with maximum warnings.
1
2
3
4
5
6
7
$ g++ -std=c++11 -Wall main.cpp
main.cpp: In member function ‘std::__cxx11::string Triangle::triangleShape()’:
main.cpp:50:33: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
     } else if ((side1 == side2) && (side1 != side3) || (side2 == side3)
                                 ^
main.cpp:51:56: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
                && (side2 != side1) || (side1 == side3) && (side1 != side2)) {

&& binds stronger than ||, and this will alter the logic to something you might not have intended.
https://en.cppreference.com/w/cpp/language/operator_precedence

Topic archived. No new replies allowed.