Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have written a function for getting the list of names and doing the comparison, what I am trying now in the main is to take the last name and interchange it with the first and then do the sorting using the comparison function to the 2d array to have everything in alphabetical order as the question asks me to.

I am very new to programming, descriptive answers would be much appreciated. Thank you.



Write a C++ program to prompt the user to enter a number of names, then print out all the names in alphabetical order of the last names. If the last names are the same, then the first names are compared. A sample run is attached as follows (the text in bold face is user input):

How many names do you want to enter? 5
Enter name #1: Bill Gates
Enter name #2: Michael Jackson
Enter name #3: Tony Blair
Enter name #4: Janet Jackson
Enter name #5: Oprah Winfrey
The names in order are:
Blair, Tony
Gates, Bill
Jackson, Janet
Jackson, Michael
Winfrey, Oprah

The strings we are using in this program are C-strings. You cannot use C++ <string>. And, you cannot use any <cstring> library function other than the overloaded operator << and operator >>


What I have tried:

int compare_C_strings(char s1[], char s2[])
{
    int lenS1 = 0;
    while(s1[lenS1] != NULL)
        {
            lenS1++;
        }

    int lenS2 = 0;
    while(s2[lenS2] != NULL)
        {
            lenS2++;
        }

    for(int i =0; (i < lenS1) || (i < lenS2); i++)
    {
        if(s1[i] > s2[i])
            return 1;
        if(s1[i] < s2[i])
            return -1;
    }
    return 0;
}


char** name_list1(int n)
{
    char** array1 = new char*[n];
    for(int i =0; i < n; i++)
    {
        array1[i] = new char[20];
    }

    //char names[n][20];
    for(int i = 0; i < n; i++)
    {
        cout << "Enter name #" << i+1 << ": ";
        cin.getline(array1[i], 20);
    }
    return array1;
}


int main()
{
    int Number_of_names;
    cout << "How many names do you want to enter? ";
    cin >> Number_of_names;
    cin.ignore(1000,'\n');

    char** names = new char*[Number_of_names];
    for(int i =0; i < Number_of_names; i++)
    {
        names[i] = new char[20];
    }
    names = name_list1(Number_of_names);

    for(int i = 0; i < Number_of_names; i++)
    {
        cout << "Name with index " << i+1 << ": " << names[i] << endl;
    }

     for(int i = 0; i < Number_of_names; i++)
    {
        for(int j = 0; names[i][j] != NULL; j++)
        {
            if(names[i][j] == ' ')
            {
                int v = j;
                for(int k = 0; names[i][v+1] != NULL; k++)
                {
                    char temp = names[i][v+1];
                    names[i][v+1] = names[i][k];
                    names[i][k] = temp;
                    v++;
                }
            }
        }
    }

    for(int i = 0; i < Number_of_names; i++)
    {
        cout << "Name with index " << i+1 << ": " << names[i] << endl;
    }





    return 0;
}
Posted
Updated 12-Sep-21 10:40am
v2
Comments
Richard MacCutchan 5-Aug-21 10:18am    
You could use the strok function to split the strings so you can find the surname for each entry. You are creating the names array twice, once in main, and once in name_list1; you only need to do it in name_list1. It may be easier to use a struct to hold the two parts of the name and split it as you read it in.
Subhranil Dey 5-Aug-21 10:28am    
Hi sir, I am using the names array twice because in main I am allocating space for the 2d array returned through pointers.
Unfortunately, I don't think I am allowed to use stroke or struct, they were not taught in the course. This is an absolute C++ beginners course, the functions we needed were taught to create ourselves.
Is there any other way I can solve this problem? I have been working on this for 2 days now
Richard MacCutchan 5-Aug-21 11:13am    
No ,you do not need to create the names array twice. You create it in name_list1 and return it to the caller in main. So the original one that you created in main is now hidden.

OK, so you are not allowed to use C functions, so you need to write your own versions. To split the name you just need to search for the space character between the surname and forename. If you save a pointer to each part then you can use those to sort the entries and to print the names in the order required.
Subhranil Dey 5-Aug-21 12:17pm    
Oh Thanks, I would use that to finally print the array. Do You have a recommendation to go about the sorting using the lastnames?
Richard MacCutchan 5-Aug-21 12:24pm    
It's the same issue; find the space between first and last names, and use the second part as your primary sort key.

Because you are in C++ you should classes and objects. Use the string which has a compare function.

When you create a Person class than you can not only write a printFullName but also some compare function and so write some more elegant code.

Tip: use vector to store and sort the person objects.
 
Share this answer
 
Comments
CPallini 5-Aug-21 10:45am    
He cannot use the string class (requirements of his homework).
KarstenK 6-Aug-21 4:22am    
Oh, thats bad but no problem. He can implement an own compare in his class. But he can use vector.
As Richard Mc Cutchan pointed out, memory is allocated unnecessarily. As the pointer is overwritten, a memory leak occurs because the memory can no longer be released. In general, allocated memory should be released again somewhere.

The process should roughly look like this:

C++
int main()
{
	int Number_of_names;
	cout << "How many names do you want to enter? ";
	cin >> Number_of_names;
	cin.ignore(1000, '\n');

	char** names = NULL;
	// Do NOT allocate twice!!
	// names = new char*[Number_of_names];
	// for (int i = 0; i < Number_of_names; i++) {
	//	 names[i] = new char[20];
	// }
	names = name_list_input(Number_of_names);

	name_list_output(names, Number_of_names);

	name_list_lastsort(names, Number_of_names);

	name_list_output(names, Number_of_names);

	// dont forget to free allocated memory!
	name_list_free(names, Number_of_names);

	return 0;
}

I´m not Shure if you are not allowed to use strlen which would make sense.
C++
int mystrlen(char* s) 
{
	int i;
	for (i=0; s[i] != NULL; i++);
	return i;
}

int compare_C_strings(char* s1, char* s2)
{
	int lenS1 = mystrlen(s1);
	int lenS2 = mystrlen(s2);
	int n = (lenS1 <= lenS2) ? lenS1 : lenS2;

	for (int i = 0; i<n; i++) {
		if (s1[i] > s2[i])
			return 1;
		if (s1[i] < s2[i])
			return -1;
	}
	return 0;
}

The alphabetical order of the last names could look like this:
C++
void name_list_lastsort(char**names, int n)
{
	int* sep = new int[n];  // allocate array of n int

	// find last names
	int j = 0;
	for (int i = 0; i < n; i++) {
		for (j = 0; (names[i][j] != NULL) & (names[i][j] != ' '); j++);
		sep[i] = (names[i][j] == ' ') ? j+1 : 0;
	}

	// sort names
	for (int i=0; i<n-1; i++) {
		for (j=i+1; j<n; j++) {
			switch (compare_C_strings(names[i] + sep[i], names[j] + sep[j])) {
			case 1: { ... }
				break;
			case 0: { ... }
				break;
			}
		}
	}

	delete []sep;  // deallocate array
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900