Heres the assignment:

Write a program that will perform sorting and searching across records stored in a file.
The program should first query the user for a filename. The program should open the file and read
the first entry. It defines the number of records in the file. The program should read each record
and store it into memory. Each record in the file will have sets of three lines. Each set consists of:
lastname, firstname, and birthdate.
Your program should prompt the user for a command:
Searching - The user should be able to supply a search value and your program should
print any entries that start with that value. You should search all first names, last names,
and birthdates. There may be multiple values returned.
Sorting - The user should be able to choose to print the data in its original unsorted form,
sorted by first name, or sorted by last name.
Quit – Exit the program

And the input file:

5
Smith
John
01/15/1971
Jones
Ed
06/23/1980
Burns
Sally
03/03/1938
Sinatra
Frank
12/12/1915
Clarkson
Kelly
04/24/1982

So I got the codes as following and it runs without any problem. The only one thing that I'm stuck with right now is my codes do not sort properly if there are identical first names, or last names. Specifically, if that is the case, it will only print one of the identical either first name or last name, and skip the others (it still reads and prints out the rest though). Is there any way other than what I'm using below during the sorting step (by first/last name) that I can use instead?

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

void getdata(ifstream&, string[], string[], string[], int); 
                                    // input data to parallel arrays holding first names
                                    // last names, and birthdates.
void getorder(string[], string[], int[], int); // assume that there is no identical first names or last names

int main()
{
    ifstream inputfile; 
    string filename, command;
    int n; 

    cout << "Please enter the file name: ";
    cin >> filename;

    // Open input file
    inputfile.open(filename.c_str());
    inputfile >> n; // Input number of records to n

    string last[n], first[n], birth[n]; // 3 arrays holding last and first names
                                        // and birthdates.  

    getdata(inputfile, last, first, birth, n); // Input data from input file to 3 arrays, using n

    inputfile.close();
    // Close input file

    // For this command, assume that user will only enter either one of these:
    // Exit, exit, searching, Searching, sorting, Sorting.
    do
    {
        cout << "Please enter Searching to search for specific records, or Sorting to sort records, or Exit to end the program: ";
        cin >> command;
        cout << endl;

        // Searching command
        if (command == "Searching" || command == "searching")
        {
            string search_value;
            cout << "Please enter the search value: ";
            cin >> search_value;
            cout << endl;

            // for searching of birthdate
            if ( isdigit(search_value.at(0)) ) // checking if search value starts with a digit -> birthdate
                                               // assume user enters input in correct format
            {
                bool found = false;
                for (int index = 0; index < n; index++)
                {
                    if (search_value == birth[index]) // check if search value matches with birthdate
                    {
                        cout << last[index] << endl;
                        cout << first[index] << endl;
                        cout << birth[index] << endl;
                        found = true;                   
                    }
                }
                if (!found) 
                {
                    cout << "There is no record matches the search value. Make sure you enter the input in ";
                    cout << "correct format.";
                    cout << endl;
                }
                cout << endl; 
            } // end of searching birthdate

            else // begin searching for last-first names.
            {
                string check;
                bool found = false;
                cout << "Please enter first if you are searching for first names, or last if you are searching for last names: ";
                cin >> check;
                cout << endl;

                // begin searching for first name
                if (check == "first" || check == "First")
                {
                    for (int index = 0; index < n; index++)
                    {
                        if (search_value == first[index]) // check if search value matches with first name
                        {
                            cout << last[index] << endl;
                            cout << first[index] << endl;
                            cout << birth[index] << endl;
                            found = true;                   
                        } 
                    } // end for statement 
                }   // end searching for first name

                else // begin searching for last name - assume that user enters only either first or last.
                {
                    for (int index = 0; index < n; index++)
                    {
                        if (search_value == last[index]) // check if search value matches with first name
                        {
                            cout << last[index] << endl;
                            cout << first[index] << endl;
                            cout << birth[index] << endl;
                            found = true;                   
                        } 
                    } // end for statement 
                } // end searching for last name

                if (!found) 
                {
                    cout << "There is no record matches the search value. Remember the searching process is";
                    cout << "case sensitive.";
                    cout << endl;
                }   
                cout << endl;
            } // end of searching for last-first names case         

        } // end of searching command

        // Sorting command
        if (command == "Sorting" || command == "sorting")
        {
            string check;
            cout << "Please enter what kind of sorting you would like to see.";
            cout << " It should be either unsorted, firstname, or lastname: ";
            cin >> check;
            cout << endl;

            if (check == "unsorted" || check == "Unsorted")
            {
                cout << "Here is the unsorted list of records: \n";
                for (int index = 0; index < n; index++)
                {
                    cout << last[index] << endl;
                    cout << first[index] << endl;
                    cout << birth[index] << endl;                                               
                } 
            } // end printing unsorted list
            else 
            if (check == "firstname" || check == "Firstname") // sorting by first names
            {
                string sorted_fn[n]; // create a duplicated array holding first names
                int order[n];   // for order of subscripts

                for (int i = 0; i < n; i++)
                {
                    sorted_fn[i] = first[i];
                } // copy the first name array to sorted_fn array

                getorder(first, sorted_fn, order, n); // get the order of subscripts

                for (int j = 0; j < n; j++)
                {
                    cout << last[order[j]] << endl;
                    cout << first[order[j]] << endl;
                    cout << birth[order[j]] << endl;
                }
            } // end printing list sorted by first name
            else // sorting by last names
            {
                string sorted_ln[n]; // create a duplicated array holding last names
                int order[n];   // for order of subscripts

                for (int i = 0; i < n; i++)
                {
                    sorted_ln[i] = last[i];
                } // copy the last name array to sorted_ln array

                getorder(last, sorted_ln, order, n);

                for (int j = 0; j < n; j++)
                {
                    cout << last[order[j]] << endl;
                    cout << first[order[j]] << endl;
                    cout << birth[order[j]] << endl;
                }
            } // end printing list sorted by first name

        }// end sorting command
    } // end do statement
    while (!(command == "Exit" || command == "exit"));          

    cout << "Done!";

    return 0;
}

void getdata(ifstream& inputfile, string last[], string first[], string birth[], int n)
{
    for (int i = 0; i < n; i++)
    {
        inputfile >> last[i];
        inputfile >> first[i];
        inputfile >> birth[i];
    }   
}

void getorder(string name[],string sorted_array[], int order[], int size) 
                        // name[] is used for comparision only
{
    int min_index;
    string min_value;
    for (int start_index = 0; start_index < (size-1); start_index++)
    {
        min_index = start_index;
        min_value = sorted_array[start_index];
        for (int k = (start_index + 1); k < size; k++)
        {
            if (sorted_array[k] < min_value)
            {
                min_value = sorted_array[k];
                min_index = k;
            }
        }
        sorted_array[min_index] = sorted_array[start_index];
        sorted_array[start_index] = min_value;
    } // sorted list by first/last names ready to be compared.

    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            if (sorted_array[i] ==  name[j])
            {
                order[i] = j;
            } 
        }
    } // end comparing two arrays. get values for order[]
}

Do you have to use 3 parallel arrays or can you use a class/struct? If you have to use the parallel array then you need to sort all of them at the same time. It would look something like this

string firstNames[];
string lastNames[];
string birthDates[];
// load the array with data

// sorting loop
for(int i = 0; i < sizeOfArrays; i++)
{
    string temp;
    for(int j = i + 1; j < sizeOfArrays; j++)
    {
        if (firstNames[i] > firstNames[j])
        {
            temp = firstNames[i];
            firstNames[i] = firstNames[j];
            firstNames[j] = temp;

            temp = lastNames[i];
            lastNames[i] = lastNames[j];
            lastNames[j] = temp;

            temp = birthDates[i];
            birthDates[i] = birthDates[j];
            birthDates[j] = temp;
        }
    }
}

So does that mean I need to create 3 duplicates of first names, last names and birthdates? Because If I'm making changes on the original ones, I cannot print the list of records in its original unsorted form? And yeah I dont think we get to class/struct yet so arrrays would most likely be prefered.

could you use a multidimensional array?

string person[n][3]

for (int i = 0; i < n; i++)
{
    for (int j = 0; j < 3; j++)
    {
        inputfile >> person[i][j];
    }
} 

this way the sample from NathanOliver would look something like this

    // load the array with data
    // sorting loop
void Sorter(string person[][3],int SortField)
{
    for(int i = 0; i < sizeOfArrays; i++)
    {
        string temp;
        for(int j = i + 1; j < sizeOfArrays; j++)
        {
            if (person[i][SortField] > person[j][SortField])
            {
                for(int k = 0;k<3;k++)
                {
                    temp = person[i][k];
                    person[i][k] = person[j][k];
                    person[j][k] = temp;
                }
            }
        }
    }
}

Sorting by a different field would be a simple matter of passing the corresponding integer of the second dimension of the array

One warning, while this sort method will work, large amounts of data will sort very slow.

Edited 3 Years Ago by tinstaafl

This article has been dead for over six months. Start a new discussion instead.