Sorting a pointer to vector of pointers to string

Hello all,

This is an lab exercise for school, and I'm trying to figure out how to sort a pointer to vector of pointers to string. FileProcessor.h and Main.cpp cannot be modified, and it's from my professor. I'm working on FileProcessor.cpp, everything works except void FileProcessor::sortData(). I tried using the sort function although it doesn't work, i think cause it's pointing to a vector?

FileProcessor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <string>
using std::string;

#include <vector>
using std::vector;

#ifndef FILEPROCESSOR_H
#define FILEPROCESSOR_H
class FileProcessor
{
public:
	FileProcessor();
	~FileProcessor();
	void readFile(const string& fileName);
	void sortData();
	void writeFile(const string& fileName);
private:
	string* fileName;
	vector<string*>* namesPtr; // pointer to vector of pointers to string
	class compareNames; // inner function class for use with STL sort
	FileProcessor(const FileProcessor& rvalue); // not implemented
	FileProcessor& operator=(const FileProcessor& rvalue); // not implemented
};
#endif 


FileProcessor.cpp
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
#include "FileProcessor.h"

#include <fstream>
using std::ifstream;
using std::ofstream;

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::ios; // ios::out, ios::app

#include <iomanip>
using std::setw;

#include <algorithm>
using std::sort;

const int MAX_RECORDS = 8;

FileProcessor::FileProcessor()
{
	namesPtr =  new vector<string*>();
}

FileProcessor::~FileProcessor()
{

}

void FileProcessor::readFile(const string& fileName)
{
	string *name[MAX_RECORDS];
	ifstream inputFile(fileName, ios::in); // read in records

	if(inputFile.fail())
	{
		cout << "Input file cannot be read";
		exit(1);
	}
	else
	{
		for(int i = 0; i < MAX_RECORDS; i++)
		{   
			name[i] = new string("");
			inputFile >> setw(21) >> *name[i];
			namesPtr->push_back(name[i]);
			if(inputFile.eof()) { break; } // check it here to stop counting
		}
	}
	inputFile.close();
}

void FileProcessor::sortData()
{
	if(namesPtr->empty())
	{
		cout << "Nothing to sort" << endl;
	}
	else
	{
		cout << "sorting data in vector" << endl;
		sort(namesPtr->begin(), namesPtr->end());
	}
	for(int i = 0; i < MAX_RECORDS; i++)
		cout << *namesPtr->at(i);
}

void FileProcessor::writeFile(const string& fileName)
{
	ofstream outputFile(fileName, ios::out);

    int recordIndex = 0;

    if(outputFile.fail())
    {
        cout << "Output file could not be written to, program will shut down.";
        exit(1);
    }
    else
    {
        for(int i = 0; i < MAX_RECORDS; i++)
        {
			outputFile << *namesPtr->at(i) << " ";
			i++;
		    outputFile  << *namesPtr->at(i) << " " << endl;
        }
    }
}


Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "FileProcessor.h"
#include <iostream>
using std::cout;
using std::endl;

int main()
{
	FileProcessor fp;

	cout << "Reading Names.txt" << endl;
	fp.readFile("Names.txt");

	cout << "Sorting names" << endl;
	fp.sortData();

	cout << "Writing Names2.txt" << endl;
	fp.writeFile("Names2.txt");
	system("PAUSE");
	return 0;
}
in your function: void FileProcessor::readFile(const string& fileName) you create an array of std::string*. Why? Why not just read into a single std::string and put that into your vector?
For your sort function, the problem is you don't want to sort the pointers which is what you are doing at the moment. You want to sort the things they point to.

So you need to pass a third parameter to std::sort():

http://www.cplusplus.com/reference/algorithm/sort/

The third parameter is a function that compares two elements of the vector. Those two elements are std::string pointers. So you need to bear that in mind when you compare them.
Hmm, alright. I've been looking at more examples and I found...

1
2
3
4
5
6
7
class comparePets
{
public:
    bool operator() (const Pet* ptrP1, 
                     const Pet* ptrP2) const
    { return *ptrP1 < *ptrP2; } // use overloaded < operator
};


Does this mean that were overloading the () operator that passes 2 pointers to pet objects? (const Pet* ptrP1, const Pet* ptrP2)

1
2
    const bool operator < (const Pet& p) const
    { return this->name < p.name; }


I dont really understand why there overloading the < operator with 1 pointer to pet objects... (const Pet& p) shouldn't it be 2 for *ptrP1 < *ptrP2???
A binary operator can be a member function, with an implicit "this" argument:
x.operator<(y)

or a global, non-member function:
operator<(x, y)


for example:
http://www.cplusplus.com/reference/string/operators/
http://www.cplusplus.com/reference/string/string/operator+=/

Generally, I would recommend having non-modifying operators as non-member functions, since they generally don't need access to the internals. (No one expects y=x+z to modify x or z). The operator example you found accesses internal members of the object, so it would have to be written differently to use a non-member version, unless those members are declared public.
Topic archived. No new replies allowed.