5 Replies - 1713 Views - Last Post: 02 April 2012 - 10:18 AM Rate Topic: -----

#1 dekker13  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 42
  • Joined: 12-September 11

Sorting an array of pointers?

Posted 01 April 2012 - 05:09 PM

I'm trying to sort an array of pointers by last name. The class is using inheritance with parent protected data: char last[21]; I have a sample function, but it's running in an infinite loop. I'm trying to sort the list alphabetically by last name. Can someone tell me what's wrong? Thanks.
void Sort(int count, Student* s[])
{
    bool swapped = true;
    Student* temp;

        do {
            swapped = false;
        
            for(int i = 0; i < count-1; i++)
            {
                if(strcmp(s[i]->getLast(), s[i+1]->getLast())  <  0 )
                {
                    temp = s[i];
                    s[i] = s[i+1];
                    s[i+1] = temp;

                swapped = true;
                }
                cout << "Address is: "<<s[i]<<endl;

            }

            } while(swapped == true);
}



Part of main.cpp
int main ()
{
    char * inputFile;
    char outputFile[MAXFILENAMESIZE];
    int sCount = 0;

    //Get a VALID input file.
    inputFile = givemeinput();    

    cout << "Please enter the name of the output file.\n";
    cout << "Filename: ";
    cin >> outputFile;

    //Create an ouput file for use.
    ofstream fout (outputFile, ios::app);  

    //Get the number of students to read in.
    sCount = studentCount(inputFile);

    //Declaration of array of pointers.
    Student** sArray;

    //Implementing the actual work. Loads pointer
    //sArray with all information.
    sArray = fillArray(inputFile, sCount, sArray);

    //Print all the information to our specified file.
    PrintToFile(sCount, sArray, fout);
    cout << "Processing Complete\n";

    for(int i = 0; i < sCount; i++)
        delete sArray[i];

   // Sort(sCount, sArray);

    return 0;
}



HEADER file
class Student 
{
    public:
        Student();
        Student(char* l, char* f, char* c);

        //Both are pure virtual functions. Retrieves specific
        //data from derived classes.
        virtual double ComputeAverage()=0;
        virtual int getFinal()=0;
        char* getLast();
        char* getCourse();
        char* getFirst();

    protected:
        char last[21];
        char first[21];
        char course[10];
};

class English : public Student 
{
    public:
        English();
        English(char* l, char* f, char* c, int attEND, int proJ,
                int miD, int finalEXAM);

    private:
        double ComputeAverage();
        int getFinal();
        int attend;
        int proj;
        int midterm;
        int finalExam;
};

class History : public Student 
{
    public:
        History();
        History(char* l, char* f, char* c, int term, int mid,
                int final);

    private:
        //ComputeAverage() and getFinal() are called from the
        //pure virtual function in the 'Student' class.
        double ComputeAverage();
        int getFinal();
        int termPaper;
        int midterm;
        int finalExam;
};

class Math : public Student
{
    public:
        Math();
        Math(char* l, char* f, char* c, int qOne, int qTwo, 
             int qThree, int qFour, int qFive, int tOne, int tTwo, 
             int final);

    private:
        //ComputeAverage() and getFinal() are called from the
        //pure virtual function in the 'Student' class.
        double ComputeAverage();
        int getFinal();
        int quiz_Average;
        int quizOne;
        int quizTwo;
        int quizThree;
        int quizFour;
        int quizFive;
        int testOne;
        int testTwo;
        int finalExam;
};


This post has been edited by dekker13: 01 April 2012 - 05:16 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Sorting an array of pointers?

#2 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Sorting an array of pointers?

Posted 01 April 2012 - 09:02 PM

You don't show any code that creates an array of pointers. So the first question is, do you actually create an array of Student* anyplace, or do you only declare the Student** sarray which is just a pointer to a Student*.

And is it your intention to sort the array backwards? Because if I'm not mistaken that's what your Sort does.

Also, your bubble sort could be more efficient. There's no need to go all the way to the end of the array on every iteration. You should shorten the scan by 1 element on each iteration.

This post has been edited by r.stiltskin: 01 April 2012 - 09:06 PM

Was This Post Helpful? 0
  • +
  • -

#3 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1276
  • View blog
  • Posts: 4,396
  • Joined: 19-February 09

Re: Sorting an array of pointers?

Posted 01 April 2012 - 09:14 PM

Hi. Are you deleting the array before sorting it?

31	    for(int i = 0; i < sCount; i++)
32	        delete sArray[i];
33	 
34	   // Sort(sCount, sArray);


Was This Post Helpful? 0
  • +
  • -

#4 dekker13  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 42
  • Joined: 12-September 11

Re: Sorting an array of pointers?

Posted 02 April 2012 - 05:03 AM

View Post#define, on 01 April 2012 - 09:14 PM, said:

Hi. Are you deleting the array before sorting it?

31	    for(int i = 0; i < sCount; i++)
32	        delete sArray[i];
33	 
34	   // Sort(sCount, sArray);


Hi. No actually I added that in lastly. I commented out the sort code because it was an infinite loop. Good question though!

View Postr.stiltskin, on 01 April 2012 - 09:02 PM, said:

You don't show any code that creates an array of pointers. So the first question is, do you actually create an array of Student* anyplace, or do you only declare the Student** sarray which is just a pointer to a Student*.

And is it your intention to sort the array backwards? Because if I'm not mistaken that's what your Sort does.

Also, your bubble sort could be more efficient. There's no need to go all the way to the end of the array on every iteration. You should shorten the scan by 1 element on each iteration.

And I didn't post all code because I don't want to reveal my solution for others doing this assignment to copy. Here's the main snippet of code. The bubble sort was a bare bones example that I tried. I've never implemented it on an array of pointers so it's a shot in the dark. Makes sense to do one less though.
ifstream myFile;
    myFile.open(filename);
    char last[21], first[21], course[10];
    char garbage[3];

    int garbageNumber;
    Student **s = new Student*[sCount];
    myFile >> garbageNumber;

    for (int i = 0; i < sCount; i++)
    {
            myFile.ignore(1);
            myFile.getline(last, 21, ',');
            myFile.ignore(1,' ');
            myFile.getline(first, 21, '\n');
            myFile.getline(course, 10, ' ');

            //Specific cases for each course. Different data for each.
            if ( strcmp(course, "Math") == 0 ) 
            {  
                int one=0,two=0,three=0,four=0,five=0,tOne=0,tTwo=0,fin=0;
                myFile >> one >> two >> three >> four >> five
                       >> tOne >> tTwo >> fin;
                     
               s[i] = new Math(last, first, course, one, two,
                          three, four, five, tOne, tTwo, fin);               
            }
            else if ( strcmp(course, "History") == 0 )
            {
                int term=0, midterm=0, finalExam=0;
                myFile >> term >> midterm >> finalExam;
                       
               s[i] = new History(last, first, course, term,
                         midterm, finalExam);                                
            }
            else if ( strcmp(course, "English") == 0 )
            {
                int attend=0, proj=0, midterm=0, finalExam=0;
                myFile >> attend >> proj >> midterm >> finalExam;
                       
               s[i] = new English(last, first, course, attend, proj,
                        midterm, finalExam);
            }
    }
    myFile.close();

    return s;


Here's the input file, if it matters:
8
Bunny, Bugs
Math 90 86 80 95 100 99 96 93
Schmuckatelli, Joe
History 88 75 90
Dipwart, Marvin
English 95 76 72 88
Crack Corn, Jimmy
Math 44 58 23 76 50 59 77 68
Kirk, James T.
English 40 100 68 88
Lewinsky, Monica
History 60 72 78
Phelps, Darrel
Math 98 94 82 98 90 87 90 34
Kowalski, Daniel
History 98 100 94

This post has been edited by dekker13: 02 April 2012 - 05:05 AM

Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5643
  • View blog
  • Posts: 12,359
  • Joined: 16-October 07

Re: Sorting an array of pointers?

Posted 02 April 2012 - 05:32 AM

Your sort looks find ( kudos for a real bubble sort! ), though it's descending rather than ascending...

Print your list before and after sort. Make sure you have what you think you have.

I did a quick test:
#include <iostream>
#include <cstring>


class Student {
public:
	static const int LAST_SIZE = 21, FIRST_SIZE = 21;
    Student(const char *last, const char *first);
    const char *getLast() const;
    const char *getFirst() const;

protected:
    char last[LAST_SIZE], first[FIRST_SIZE];
};

void Sort(int count, Student *s[]);
void print(int count, Student *s[]);

using namespace std;

int main() {
	const int size = 3;
	Student *a[size] = { 
		new Student("Bolton", "Chuck"), 
		new Student("Carter", "John"), 
		new Student("Alan", "Fred"),
	};
	print(size, a);
	Sort(size, a);
	print(size, a);
	return 0;
}

void Sort(int count, Student *s[]) {
	bool swapped = true;
	while(swapped) {
		swapped = false;
		for(int i = 0; i < count-1; i++) {
			if(strcmp(s[i]->getLast(), s[i+1]->getLast())  >  0 ) {
				Student *temp = s[i];
				s[i] = s[i+1];
				s[i+1] = temp;
				swapped = true;
			}
		}
	}
}

void print(const Student &s) {
	cout << s.getLast() << ", " << s.getFirst() << endl;
}

void print(int size, Student *s[]) {
	for(int i=0; i<size; i++) {
		cout << (i+1) << ". ";
		print(*s[i]);
	}
	cout << "---------" << endl;
}

Student::Student(const char *l, const char *f) {
	strncpy(last, l, LAST_SIZE-1); last[LAST_SIZE-1] = 0;
	strncpy(first, f, FIRST_SIZE-1); first[FIRST_SIZE-1] = 0;
}
const char *Student::getLast() const { return last; }
const char *Student::getFirst() const { return first; }




It would be super cool if you overloaded the < operator in Student, though. This would buy you an easy compare for your custom sort, or the ability to use the C++ canned one.

Any reason not to use std::string? If not, use that instead.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#6 dekker13  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 42
  • Joined: 12-September 11

Re: Sorting an array of pointers?

Posted 02 April 2012 - 10:18 AM

View Postbaavgai, on 02 April 2012 - 05:32 AM, said:

Your sort looks find ( kudos for a real bubble sort! ), though it's descending rather than ascending...

Print your list before and after sort. Make sure you have what you think you have.

I did a quick test:
#include <iostream>
#include <cstring>


class Student {
public:
	static const int LAST_SIZE = 21, FIRST_SIZE = 21;
    Student(const char *last, const char *first);
    const char *getLast() const;
    const char *getFirst() const;

protected:
    char last[LAST_SIZE], first[FIRST_SIZE];
};

void Sort(int count, Student *s[]);
void print(int count, Student *s[]);

using namespace std;

int main() {
	const int size = 3;
	Student *a[size] = { 
		new Student("Bolton", "Chuck"), 
		new Student("Carter", "John"), 
		new Student("Alan", "Fred"),
	};
	print(size, a);
	Sort(size, a);
	print(size, a);
	return 0;
}

void Sort(int count, Student *s[]) {
	bool swapped = true;
	while(swapped) {
		swapped = false;
		for(int i = 0; i < count-1; i++) {
			if(strcmp(s[i]->getLast(), s[i+1]->getLast())  >  0 ) {
				Student *temp = s[i];
				s[i] = s[i+1];
				s[i+1] = temp;
				swapped = true;
			}
		}
	}
}

void print(const Student &s) {
	cout << s.getLast() << ", " << s.getFirst() << endl;
}

void print(int size, Student *s[]) {
	for(int i=0; i<size; i++) {
		cout << (i+1) << ". ";
		print(*s[i]);
	}
	cout << "---------" << endl;
}

Student::Student(const char *l, const char *f) {
	strncpy(last, l, LAST_SIZE-1); last[LAST_SIZE-1] = 0;
	strncpy(first, f, FIRST_SIZE-1); first[FIRST_SIZE-1] = 0;
}
const char *Student::getLast() const { return last; }
const char *Student::getFirst() const { return first; }




It would be super cool if you overloaded the < operator in Student, though. This would buy you an easy compare for your custom sort, or the ability to use the C++ canned one.

Any reason not to use std::string? If not, use that instead.

Hope this helps.


Yeah, I could have used the <string> class but I wanted more practice with char arrays, c-style strings and the like. I noticed you added 'const' which I should have known better. Doesn't affect the code but best practices. :wink: I'll keep thinking about this.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1