Help with sorting Structs within an Array

Thanks for the help everyone. I'm writing a program to save data from a struct to a file and then sort it. Everything seems to be going fairly well but when I try to sort my the strings of my struct the order is not correct. I am quite stuck and since I am getting no errors when compiling i've hit a dead end. If anyone could look over my code and let me know what I need to change in the functions "void sort_by_title" and "sort_by_genre" to get the results to display in alphabetical order it would be greatly appreciated.

Note: Since the length limit won't allow me to post all of my code, I have removed the functions displaycollection(), newcollection(), and newmovie() as they are all working and aren't relavent to the question.

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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
//program must exit from menu in order to save

#include <iostream>
#include <fstream>
#include <stdio.h>              // for printf()
#include <stdlib.h>        
#include <string.h>
using namespace std;

struct my_movies                //declare structure my_movies
{
	string title;	  	// title
	int year_rel;	  	// year released
	string genre;		//genre
	
};                          //end structure declaration

my_movies movies_data [50];         //array of 50 structures
my_movies buffer [50];                //buffer for movies_data array values
int n=0;							//number of movies in collection



void loaded_collection();
void newmovie();
void displaycollection();
void Newcollection();
void delete_movie();
void sort_by_title();
void sort_by_year();
void sort_by_genre();

int main()
{ //                                                              INT MAIN START
    ifstream fin("Movie_List.txt");   //load or create new list
    if(fin.good()){
        cout << "Import successful\n";
        cout << "Press enter to continue\n";
        ifstream fin("Movie_List.txt");
        while(fin.good()) // Load all data
        {
            
            fin >> n >> movies_data[n].title >> movies_data[n].year_rel >> movies_data[n].genre;
        }
        fin.clear();
        loaded_collection();}
    else
        {
        Newcollection();
        }
}       





void exit_program()                 //exits and saves list
{
    ofstream fout("Movie_List.txt");
    for (int c=1; c <= n ; c++) // Re-upload all data to new file
    {fout << c << " " << movies_data[c].title << " " << movies_data[c].year_rel << " " << movies_data[c].genre
        << " " << endl;}
    exit(0);
}

void delete_movie()
{
    int y,z;
    if (n < 1)
        {                        // check for empty list
            printf("\nEmpty list.\n");
        }
    for (y=1; y<=n; y++)                 // print list
        {
            cout <<"Movie Number " <<y <<" is " <<movies_data[y].title <<endl;
        
            
            //printf("\nMovie Number %d", y);
            //printf(" %s\n", movies_data[y].title);
        }  
    
    cout <<"Enter the number of the movie you would like to delete\n";
    cin >>z;
    if (z>n || z<=0) 
        {
            cout <<"Movie does not exist in your collection." <<endl;
            loaded_collection();
        } else 
            {
                int choice;
                printf("\nMovie Number %d\n", z);
                cout <<"Title: " <<movies_data[z].title <<endl;
                printf("   Year Released: %03d\n", movies_data[z].year_rel);
                cout <<"   Genre: " <<movies_data[z].genre <<endl;
                
                cout <<"Deleted movies cannot be recovered\n";
                cout <<"  Press 1 to delete this movie\n";
                cout <<"  Press 2 to cancel\n";
                cin >>choice;
                
                if(choice==1){
                    for(; z<n; ++z)
                    {
                        y=z+1;
                        movies_data[z].title=movies_data[y].title;
                        movies_data[z].year_rel=movies_data[y].year_rel;
                        movies_data[z].genre=movies_data[y].genre;
                    }
                    n=z-1;
                    cout << "File deleted.\n";}
                    cout << "Press enter to continue.\n"; 
                    cin.ignore();
    
            }
    
}

void sort_by_genre()
{
    int m,k,j;
    //implement selection sort algorithm
    for (k=0; k<=n-1; ++k) 
    {
        //find position of smallest value in array beginning at k
        m=k;
        for (j=k+1; j<=n; ++j) 
        {
            int compare=0;
            if (compare==(movies_data[m].genre.compare(movies_data[j].genre)))  
            {
                m=j;
            }
        }
                
        //exchange smallest value with value at k
        //movies_data[0].year_rel is "cache" for variables that are being moved around
        movies_data[0].genre=movies_data[m].genre;
        movies_data[m].genre=movies_data[k].genre;
        movies_data[k].genre=movies_data[0].genre;
        
    }
    displaycollection();
    loaded_collection();
}
void sort_by_title()
{
    int m,k,j;
    //implement selection sort algorithm
    for (k=0; k<=n-1; ++k) 
    {
        //find position of smallest value in array beginning at k
        m=k;
        for (j=k+1; j<=n; ++j) 
        {
            int compare=0;
            if ((compare=(movies_data[m].title.compare(movies_data[j].title))))  
            {
                m=j;
            }
        }
        
        //exchange smallest value with value at k
        //movies_data[0].year_rel is "cache" for variables that are being moved around
        movies_data[0].title=movies_data[m].title;
        movies_data[m].title=movies_data[k].title;
        movies_data[k].title=movies_data[0].title;
    }
    displaycollection();
    loaded_collection();
}

void sort_by_year()
{
    int m,k,j;
    //implement selction sort algorithm
    for (k=0; k<=n-1; ++k) 
    {
        //find position of smallest value in array beginning at k
        m=k;
        for (j=k+1; j<=n; ++j) 
        {
            if (movies_data[j].year_rel < movies_data[m].year_rel) 
            {
                m=j;
            }
        }
        
        //exchange smallest value with value at k
        //movies_data[0].year_rel is "cache" for variables that are being moved around
        movies_data[0].year_rel=movies_data[m].year_rel;
        movies_data[m].year_rel=movies_data[k].year_rel;
        movies_data[k].year_rel=movies_data[0].year_rel;
    
    }
    displaycollection();
    loaded_collection();
}

void sort_collection()
{
    int q;
    cout <<"To sort collection alphabetically by title, press 1:\n";
    cout <<"To sort collection by the year released, press 2:\n";
    cout <<"To sort collection alphabetically by genre, press 3:\n";
    cin >>q;
    switch (q) {
        case 1:
            sort_by_title();        //doesn't exist yet
            break;
        case 2:
            sort_by_year();
            break;
        case 3:
            sort_by_genre();  //doesn't exist yet
            break;
        default:
            cout <<"Input not accepted.\n";
            break;
    }
}

void loaded_collection()
{
    ifstream fin("Movies_List.txt");
    
    while (1)
    {
        
        int x;
        cin.ignore();
        cout <<"                                                 \n";
        cout <<"Program must exit in order to save data\n";
        cout <<"'1' to enter new movie," <<endl;    //enter new
        cout <<" '2' to list current collection," <<endl;   //print selections
        cout <<"  '3' to delete a movie," <<endl;
        cout <<"   '4' to sort collection," <<endl; 
        cout<<"    '5' to save and quit: " <<endl;                  //save and quit
        x = cin.get();                            // get choice
        switch (x)
        {
            case '1':            // enter new movie
                newmovie();
                break;
            case '2':                      // list entire collection
                displaycollection();
                break;
            case '3':
                delete_movie();
                break;
            case '4':                           //sort by:
                sort_collection();
                break;
            case '5':                                //save and quit
                exit_program();
                break;
            default:                       // user error
                puts("\nInput not accepted");
                system("pause");
    		    
        }
        
    }   
}
I see too many odd procedures here...

First of all:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if(fin.good()){
        cout << "Import successful\n";
        cout << "Press enter to continue\n";
        ifstream fin("Movie_List.txt");  //why reopen the file?? it can't be good...
//(actually, as far as I know... you shouldn't be able to compile, since you are declaring fin twice...)
        while(fin.good()) // Load all data
        {
            
            fin >> n >> movies_data[n].title >> movies_data[n].year_rel >> movies_data[n].genre; 
//We have to assume your file have the entries ordered with a number...? 
//Perhaps you could try with n++ at the end of the loop, and make a reliable counter.
        }
        fin.clear();
        loaded_collection();}


why do you use printf? Since you already use cout, don't see the point on mixing them...!

But I'm not answering your question, yet. LOL

Check if your problem have something to do with this:
Notice that for string objects, the result of a character comparison depends only on its character code (i.e., its ASCII code), so the result has some limited alphabetical or numerical ordering meaning.


AAh, in Sort_by_Title's if, you left one '=':

1
2
3
4
5
6
7
            
int compare=0;
if ((compare==(movies_data[m].title.compare(movies_data[j].title)))
{
 m=j;
}
 


but, anyway:
Return Value
0 if the compared characters sequences are equal, otherwise a number different from 0 is returned, with its sign indicating whether the object is considered greater than the comparing string passed as parameter (positive sign), or smaller (negative sign).


I haven't done the all effort of understanding your algorithm, but since when you are sorting by year you check if J < m, why when sorting by title or genre you check if they are equal? you can check i j<m just like this:

1
2
3
4
5
6
7
            
int compare=0;
 if (compare<(movies_data[m].genre.compare(movies_data[j].genre)))  
 {
 m=j;
 }
        }


Meaning that if the return of compare () is greater than 0, (i.e. positive) that means that movies_data[j].genre is smaller than movies_data[m].genre.
Last edited on
Thanks. that greater than string comparison seems to have done the trick.

As for the rest of your suggestions, it is running fine in xcode and since this is my second program ever I have been working from examples and changing it as I go along. Thats why cout and printf are all mixed together and everything else is chaos in the eyes of anyone who knows what they are talking about!
Topic archived. No new replies allowed.