sorting string arrays from greatest to smallest

Hello everyone, I'm trying to work out this problem in small steps. I have two arrays one is of string value and the other of int value. The problem is the string array. The program compiles but doesn't sort the student ID's correctly. Ultimately I have to sort both arrays, but I want to figure how to do one before I tackle both.

Student ID -> student type -> courses taken. Text file looks like this:
CC333333 U 3
AA111111 G 36
BB222222 U 80
DD444444 U 52
CD334455 U 100
BC223344 U 10
AB112233 A 134
EE555555 G 18
DE445566 U 122

I have never done any sorting of arrays in C++ yet, so all this is really new to me. Any help would be appreciated. Thank you very much.

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
171
172
173
174
175
176
177
178
179
180
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cctype>
using namespace std;

// declare enumerated type globally
enum studentLevel {FRESHMAN, SOPHOMORE, JUNIOR, SENIOR}; 

// Global constants
const int MAX_ARRAY = 10;
const string IN_CREDIT_FILE  = "CREDITS.txt";
const string OUT_CREDIT_FILE = "OUT_CREDITS.txt";

// prototypes
void display_header();
void readCreditFile (ifstream&, string [], string [], int&);	
studentLevel studentNum (int);
string studentTitle (studentLevel);
void selectSort (string [], string [], int&);
//double aboveAverageExpense ();
//void displayExpenses ();

//*************************************************************************
//  FUNCTION:	  main
//  DESCRIPTION:  Asks user for a base number, then calls functions to read 
//                an exponent and compute the base raised to the exponent, and  
//                then displays the results.  Loops, requesting numbers until 
//                user enters zero for base.
//  OUTPUT:       Return Value:  0 on success
//  CALLS TO:	  GetPositiveNum, CalcAnswer
//************************************************************************* 
int main()	
{
	//VARIABLES
	int cnt = 0;								// counter used for employee coverage
	int cnt1;
	double empAverage;							// return value from the called function averageExpense for employee average
	double famAverage;  						// return value from the called function averageExpense for family average
	double empHighest;							// return value from the called function highestExpense for employee average
	double famHighest;							// return value from the called function highestExpense for family average
	double empAbove;							// return value from the called function aboveAverageExpense for employee average
	double famAbove;							// return value from the called function aboveAverageExpense for family average
	// opening the text file medical.txt
	ifstream inCreditData;						
	inCreditData.open(IN_CREDIT_FILE.c_str());
	
	// array's
	string idNum [MAX_ARRAY];
	string classLevel [MAX_ARRAY];
	
	// display header
	display_header();
  	// verification that file exists 
    if (!inCreditData)
    {	   
       cout << "The input data file does not exist!" << endl;
       cout << "Please verify input file and run the program again!" << endl;
       return 5;
    }
	// calling different functions to compute and display the results   	
	else
	{
		cout << "File opened successfully! Reading file." << endl << endl;
		readCreditFile (inCreditData, idNum, classLevel, cnt);
		selectSort(idNum, classLevel, cnt);
		
		for (cnt1 = 0; cnt1<MAX_ARRAY; cnt1++)
		{
			cout << "ID number " << cnt1 << " is" << idNum[cnt1]<< endl;
			cout << "class " << cnt1 << "is: " << classLevel[cnt1] << endl;
			cout << endl;
		}
	}	
	return 0;
}
//*************************************************************************
void readCreditFile (ifstream& inCreditData, string idNum [], string classLevel [], int& cnt)
{
	string studentId;					// stored value for the students ID number
	char ch;							// stored value for the students status
	int classesTaken;					// number of credits completed by student
	studentLevel num;					// the numerical value of the function studentClass;
	string title;						// stored value from the function studentClass
	bool arrayFull = false;			    // check to see if there is still space in the array idNum[]
	
	while(inCreditData && cnt <= MAX_ARRAY)
	{
		inCreditData >> studentId >> ch >> classesTaken;
		if (ch == 'U' && !arrayFull)
		{
			idNum[cnt] = studentId;				// store student ID into idNum array
			num = studentNum (classesTaken);	// function to compute the ordinal value 
			title = studentTitle (num);			// function to convert ordinal value to string
			classLevel[cnt] = title;			// store string value of class level into array
			cnt++;
			if (cnt >= MAX_ARRAY)				// test to see if array is full
			{
				arrayFull = true;
				cout << "Error: only the first " << MAX_ARRAY
				     << " students will be read." << endl << endl;
			}
		} // end inner if
		
	} // end while
	
	inCreditData.close();
 	
    return;
}
//*************************************************************************
studentLevel studentNum (int numCredits)
{
	studentLevel title;								
	
	if(numCredits < 32)
		 title = FRESHMAN;
	else if (numCredits >= 32 && numCredits <= 63)
		 title = SOPHOMORE;
	else if (numCredits >= 64 && numCredits <= 95)
		 title = JUNIOR;
	else 
		 title = SENIOR;

			
	return title;
} 
//***************************************************************************
string studentTitle (studentLevel level)
{
	string name;
	switch (level)
	{
		case 0: 
			name = "Freshman";
			break;
		case 1:
			name = "Sophomore";
			break;
		case 2:
			name = "Junior";
			break;
		case 3:
			name = "Senior";			
	}
		
   return name;
}
 //***************************************************************************
// IdNum = array for student ID; classLevel = array for class level; cnt= counter
void selectSort (string idNum [], string classLevel [], int& cnt)    
{
  int curTop,            // Current top of unsorted list
      tryIdx,            // Position to compare value to
      minPosition;       // Position of smallest value
      string temp;              // Temp value for swapping

  // for each item in the list (top to bottom)
  for (curTop = 0; curTop < cnt - 1; curTop++) 
  {
          
     minPosition = curTop;      // start with current top as smallest value

     // find greatest value from curTop down
     for (tryIdx = curTop + 1; tryIdx < cnt; tryIdx++) 
         if (idNum[tryIdx] > idNum[minPosition])
             idNum[minPosition] = idNum[tryIdx];
				
    // if smallest not at curTop, swap with curTop
     if (minPosition != curTop) 
     {
         temp = idNum[curTop];
         idNum[curTop] = idNum[minPosition];
         idNum[minPosition] = temp;
     }   // end swap

  }
  return;
}
Last edited on
The prototype of selectSort(...) doesn't match the implementation:
1
2
3
4
5
6
7
8
void selectSort (string, string, int&);

...

void selectSort (string idNum [], string classLevel [], int& cnt)    
{
...
}
Make sure that they match.
I knew it was something small that would kick my butt for hours. Thank you for pointing that out.
So I managed to find a way to get the idNum [] array to go from greatest to least, but it outputs the first same two greatest ID numbers. For example, DE445566 = idNum[0] and idNum[1], from there it is all correct. I'm not sure what's going on, please help.
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
// IdNum = array for student ID; classLevel = array for class level; cnt= counter
void selectSort (string idNum [], string classLevel [], int& cnt)    
{
  int curTop,            // Current top of unsorted list
      j,            // Position to compare value to
      max;       // Position of smallest value
  string temp;              // Temp value for swapping
  string temp1;
      

  // for each item in the list (top to bottom)
  for (curTop = 0; curTop < cnt - 1; curTop++) 
  {
          
     max = curTop;      // start with current top as smallest value

     // find greatest value from curTop down
     for (j = curTop + 1; j < cnt; j++) 
         if (idNum[j] > idNum[max])
         {
         	max =j;
         	idNum[max] = idNum[j];
		 }
           				
     //if greatest not at curTop, swap with curTop
     if (max != curTop) 
     {
         temp = idNum[curTop];
         idNum[curTop] = idNum[max];
         idNum[max] = temp;
     }   // end swap
  }
  return;
}
Take a look at line 22: What happens to the value of idNum[max]?

By the way. There is already a swap function in the standard library:

http://www.cplusplus.com/reference/utility/swap/?kw=swap
idNum[max] becomes idNum[j]. Running through the debug, on line 22 idNum[max] becomes DD444444. I still don't see why line 22 would make DE445566 come up in both cell 0 and 1. I must be missing something.
The problem is not what content it get, the point is that the information of that particular field is lost whereas the other field is duplicated.

What is the reason for that line? Simply remove it.
The for loop from line 18-23 is to find the greatest string and place it into max. When I delete line 22 it still is duplicating DE445566. Thank you for helping me.
Line 12: Why cnt - 1?

Otherwise show the modified code and some test data and I will check that.

Now I checked it. The culprit is line 88:

1
2
3
4
	while(inCreditData && cnt <= MAX_ARRAY)
	{
		inCreditData >> studentId >> ch >> classesTaken;
		if (ch == 'U' && !arrayFull)


You read the last line of inCreditData twice. Change to:

1
2
3
	while(inCreditData >> studentId >> ch >> classesTaken && cnt <= MAX_ARRAY)
	{
		if (ch == 'U' && !arrayFull)
Last edited on
Topic archived. No new replies allowed.