Sorry guys, am back again with another noob question and hoping someone is nice enough to help point me in the right direction.I've only began to learn this in the past couple of weeks so there is still alot am confused about. Really wish i didnt have to come here and ask dumb questions but i need to learn this by all means and nowhere else to go.

I am trying to write a program that will allow input of names in any order and sort the names based on the first character.
My code is below - it allows the names but does not sort. I know i should "store the names" somehow so i can sort and retrieve them but i dont know how.

I havent learnt sorting or array yet, just on chapter 5 of my book so i dont think i should be using those - though have tried to read-up on it but i still cant apply the concept to this simple problem.

Would appreciate any help.

Thanks.

#include<iostream>
#include<string>


using namespace std;

int main()

{

	int num_of_students;
	int x=0;
		
	string name;

	
		cout << "how many student" << endl;
	cin >> num_of_students;
	while ((num_of_students < 2)||(num_of_students > 25))
	{
			cout<<"Invalid entry"<<endl;
			cout<<"Please enter number greater than 2 and less than 25"<<endl;
			cin>>num_of_students;
			
	}

	for (x=1; x <= num_of_students; x++)	
	{
	cout << "enter name" << endl;
	cin >> name;
	
	}
	
	 cout << "the formation_line is: " << name << endl;
	
	system("PAUSE");
	return 0;


}

My guess is that you have just landed on the chapter about arrays. I could tell you about the standard library, stuff like vector etc BUT I hope that is a later chapter.
In fact, I hope that you do this exercise, three times or something like that, using different storage systems each time.

Anyway Arrays:

You seem to have understood variables, and they are just names that are going to have a type and a value. You could write this:

std::string name1,name2,name3,name4;
std::cout<<"Enter 4 names"<<std::endl;

std::cin>>name1>>name2>>name3>>name4;

Now that is ok, but what if you wanted more than 4 names, say 100. That would be VERY laborious. So to get round that you can do this:

std::string arrayOfNames[25];
std::cout<<"Enter 25 names"<<std::endl;
for(int i=0;i<25;i++)
  std::cin>>arrayOfNames[i]<<std::endl;

Now as long as the part in the square bracket correspond to a number from 0 to 24, you have effectively found a way to write arrayOfNames23 or whatever the number is.

There are two points : (a) the index runs from 0 to 24 (b) if you get it wrong and put arrayOfNames[25] what happens is undefined. i.e you can get a completely random name or your program can core dump etc.

In addition, since c++ is a relatively low level language, you can see how the code arranged the memory in reality (and hence why the strange 0 to 24 pattern above).
Consider this:

int xArray[25];
std::cout<<"Memory location for xArray[0]="
          <<reinterpret_cast<long int>(xArray)<<std::endl; 

for(int i=0;i<25;i++)
  std::cout<<"Mem location for "<<i<<" == "
   <<reinterpret_cast<long int>(&xArray[i])<<std::endl;

This is worth trying, what happens is that you are seeing the block of memory that the array is allocated to. It is a continuous block of memory, and each unit of memory is 4 or 8 bytes bigger than the last. [Note: the reinterpret_cast<long int> is just a way to avoid a compiler warning, you can ignore it, it just converts a pointer address to a long int value, i.e. a number]

The part of the array is a way of saying +i units of the object forward from the beginning.

There is another way to do this using pointers, these are almost the same, but with slight differences. So I suggest first trying to read in a number of items into an array and displaying them. As for sorting, that is fine if you know a sorting algorithm, if not do something else with the array, e.g, reverse it, it will teach the same principles.

I know I haven't given you a lot, but this is one the the key areas of c++ that just has to be understood. Please take the time and experiment with arrays, then pointers before going onto vectors etc and objects and other stuff. It really will help you.

Please feel free to post further examples / attempts to do stuff, always happy to see people attempting to learn, and you seem to be making progress from your earlier posts.

Edited 6 Years Ago by StuXYZ: n/a

Many Thanks StuXYZ - very grateful. I will work on this now and repost.

Ok - this is my updated code but it does not work correctly. Apparently, i cant do this without using an array to store and a sort function for the output. Not sure why this is so as these two topics are not covered till chapter 8 and 11 of my book and this question is on chapter 5. But oh well..

Program runs fine when i input characters "aaa,bbb,ccc" as my names but not when i input real names say "Mike, Paul, John"..

Can someone be so nice to point out what i did wrong and how to correct this?

Many thanks.

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

void sortnames(string [], int);



int main()

{
	int num_of_students;
	int x;
	
	string name [100];

	cout << "How many student" << endl;
	cin >> num_of_students;
	if (num_of_students != -1)
	{
		while (((num_of_students < 1)||(num_of_students > 25)) && (num_of_students != -1))
	      {
			cout<<"Invalid entry"<<endl;
			cout<<"Please enter number greater than 0 and less than 26"<<endl;
			cin>>num_of_students;		
	       }
	    
		   for (x=1; x <= num_of_students; x++)	
	         {
	           cout << "Enter student's first name" <<endl;
               cin >> name[x];
	         }
	    sortnames(name, num_of_students);  
		cout << "Line formation list of names: " <<endl;
		for (x=1; x <= num_of_students; x++)	
	         {
	           cout << name[x] <<endl; 
	         }     	
	}
	else
	{
		cout << "Terminating......."<<endl;
		system("PAUSE");
		return 0;
	}
	
	system("PAUSE");
	return 0;
}	
void sortnames(string name[], int num)
{
	int i,a, min;
	string strName;
	for (i = 1; i <= num; i++)
	{
		min = i;
		strName = name[i];
		for (a = i + 1; a < num; a++)
		{
			if(name[a] < strName)
			{
				strName = name[a];
				min = a;
			}
		}
		name[min] = name[i];
		name[i] = strName;
	}
}

Edited 6 Years Ago by effizy: n/a

You have a logical error in your sort. In your main, you leave name[0] unused but in your second for loop, you don't take that into account on your variable num.

void sortnames(string name[], int num){
	int i,a, min;
	string strName;
	for (i = 1; i <= num; i++)	{
		min = i;
		strName = name[i];
		for (a = i + 1; a < num; a++){
			if(name[a] < strName){
				strName = name[a];
				min = a;
			}
		}
		name[min] = name[i];
		name[i] = strName;
	}
}

Lets assume:
name[1] = Mike
name[2] = Paul
name[3] = John
num = 3 (num_of_students from main)

on the first pass through:
i = 1
min = 1
name = Mike
strName = Mike
a = i + 1 = 2

The if statement reads as if (name(a) < strName) which is Paul < Mike, it's not, so the for loop reiterates.

Now a increments by 1, and becomes 3, then cancels out of the inner loop because a < num is now false, and returns to the outer loop and poor John is left hanging at the end. You can fix that by adding to the inner loop

for (a = i + 1; a <= num; a++){

an equal sign. That should fix the issue.

Edited 6 Years Ago by kes166: n/a

What exactly is the title of Chapter 5? Can you share the exact wording of the question you are working on? Like StuXYZ mentioned, this definitely sounds like either an Introduction to Vectors or an Introduction to Arrays type of chapter.

When working with arrays, you need to be mindful of their boundaries to prevent errors and/or erratic behavior. An example program for you (this will not complete your assignment):

#include <iostream>

using namespace std;

int main() {
  const int ARRAY_SIZE = 25;      //declare a constant for the array size
  int anArray[ARRAY_SIZE] = {0};  //declare and initialize an array of ARRAY_SIZE ints
  int displayCount = 0;

  //traverse the array to assign new values, this version is an ERROR
  /*
  for (int i = 0; i <= ARRAY_SIZE; ++i) { //look closely at this line
    anArray[i] = (2 * i);
  }
  */

  //traverse the array to assign new values, this version is NOT AN ERROR
  for (int i = 0; i < ARRAY_SIZE; ++i) {  //look closely at this line
    anArray[i] = (2 * i);
  }
  
  do {
    cout << "How many elements would you like to display: ";
    cin >> displayCount;
  } while (displayCount < 1 || displayCount > ARRAY_SIZE);

  for (int j = 0; j < displayCount; ++j) {
    cout << anArray[j] << " ";
  }

  return 0;
}

I don't suspect there is anything in here that would be too foreign to you.

Looking at your code:
Line 15 string name [100]; . this is an array declaration. You have declared an array of string objects that is 100 objects long. Based on Line 24 " cout<<"Please enter number greater than 0 and less than 26"<<endl; ", this is some serious overkill. Your array should only be 26 elements at the most. In actuality, 25 is all you really need. Anything more is just wasted memory because, once properly written, any object above index 24 will never get used.

Line 54, for (i = 1; i <= num; i++) . This has the error I highlighted for you in my example. You will have to correct this.

Address these issues, then report back. There are other issues as well, see what you can find and correct.

Edited 6 Years Ago by Fbody: n/a

My sincere gratitude to all for the responses. I will revert back with updated code and hopefully a working one.

BTW - chapter 5 is Looping and this is one of its' programming problems.

Looping and arrays are heavily-linked concepts. It is pretty much impossible to properly process an array without some sort of loop. I would read the chapter again, VERY carefully. There must be some sort of data structure in it that will tell you how to handle the multiple values, perhaps not an array, but something.

My gratitude to all who responded - thanks for taking the time to do so. I will revert back with an updated code and hopefully a working one.

Chapter 5 is Looping and this is one of its' programming problems. Enter a number(of students), loop to read in that many names and display which names should be first and last on the list based on the first character of the names.

Regards

Looping and arrays are heavily-linked concepts. It is pretty much impossible to properly process an array without some sort of loop. I would read the chapter again, VERY carefully. There must be some sort of data structure in it that will tell you how to handle the multiple values, perhaps not an array, but something.

Funny you mentioned that - someone did ask the instructor and he said we should all read chapter 8 to address this problem while the class is yet to work on chapter 6. What a joke right but am stuck here for a semester..

Kes and fbody - Oh my, thanks alot..I have a working code, tested. made the changes to line 15 and 58 of my original code and outputs correctly. This is my working code for all that its worth..

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

void sortnames(string [], int);

int main()

{

	int num_of_students;
	int x;
	
	string name [25];

	cout << "How many student" << endl;
	cin >> num_of_students;
	if (num_of_students != -1)
	{
	while (((num_of_students < 1)||(num_of_students > 25)) && (num_of_students != -1))
	      {
			cout<<"Invalid entry"<<endl;
			cout<<"Please enter number greater than 0 and less than 26"<<endl;
			cin>>num_of_students;		
	       }
	    
		   for (x=1; x <= num_of_students; x++)	
	         {
	           cout << "Enter student's first name" <<endl;
               cin >> name[x];
	         }
	       
	       sortnames(name, num_of_students);  
		cout << "Line formation list of names are: " <<endl;
		for (x=1; x <= num_of_students; x++)	
	         {
	           cout << name[x] <<endl; 
	         }
	         	
	}
	else
	{
		cout << "Terminating......."<<endl;
		system("PAUSE");
		return 0;
	}
	system("PAUSE");
	return 0;
}
	
void sortnames(string name[], int num)
{
	int i,a, min;
	string strName;
	for (i = 1; i <= num; i++)
	{
		min = i;
		strName = name[i];
		for (a = i + 1; a <= num; a++)
		{
			if(name[a] < strName)
			{
				strName = name[a];
				min = a;
			}
		}
		name[min] = name[i];
		name[i] = strName;
	}
}

Many thanks again - and excuse me for asking basic/silly questions, just learning and there is alot to process.

It's not unusual for a programming class to jump around in the book. It is very difficult to create a chronology for programming lesson plans because all the concepts are so inter-linked. You can't cover arrays without covering looping, but you can't cover looping without covering if-else, switch, and relational and logical operators, etc..., etc...

When it comes to programming, the base knowledge set is fairly simple, but rather expansive. You really can't get into algorithms and useful programs until you cover the entire base. The problem is, how do you cover the entire base in a manner that isn't confusing for the student.

Edited 6 Years Ago by Fbody: n/a

Kes and fbody - Oh my, thanks alot..I have a working code, tested. made the changes to line 15 and 58 of my original code and outputs correctly. This is my working code for all that its worth..

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

void sortnames(string [], int);

int main()

{

	int num_of_students;
	int x;
	
	string name [25];

	cout << "How many student" << endl;
	cin >> num_of_students;
	if (num_of_students != -1)
	{
	while (((num_of_students < 1)||(num_of_students > 25)) && (num_of_students != -1))
	      {
			cout<<"Invalid entry"<<endl;
			cout<<"Please enter number greater than 0 and less than 26"<<endl;
			cin>>num_of_students;		
	       }
	    
		   for (x=1; x <= num_of_students; x++)	
	         {
	           cout << "Enter student's first name" <<endl;
               cin >> name[x];
	         }
	       
	       sortnames(name, num_of_students);  
		cout << "Line formation list of names are: " <<endl;
		for (x=1; x <= num_of_students; x++)	
	         {
	           cout << name[x] <<endl; 
	         }
	         	
	}
	else
	{
		cout << "Terminating......."<<endl;
		system("PAUSE");
		return 0;
	}
	system("PAUSE");
	return 0;
}
	
void sortnames(string name[], int num)
{
	int i,a, min;
	string strName;
	for (i = 1; i <= num; i++)
	{
		min = i;
		strName = name[i];
		for (a = i + 1; a <= num; a++)
		{
			if(name[a] < strName)
			{
				strName = name[a];
				min = a;
			}
		}
		name[min] = name[i];
		name[i] = strName;
	}
}

Many thanks again - and excuse me for asking basic/silly questions, just learning and there is alot to process.

It looks like you are still not using name[0], and you declared string name[25] which will create locations for name[0], name[1], ... , name[24]. If you create the maximum number of students, the last student will be entered into name[25] which will not exist so your program will break if you try to enter 25 students. You can try it just to be sure, but if you make your declaration string name[26] that should fix the problem instead of having to rewrite your for loops.

It looks like you are still not using name[0], and you declared string name[25] which will create locations for name[0], name[1], ... , name[24]. If you create the maximum number of students, the last student will be entered into name[25] which will not exist so your program will break if you try to enter 25 students. You can try it just to be sure, but if you make your declaration string name[26] that should fix the problem instead of having to rewrite your for loops.

You make a good point about the indexes, but this is bad advice.

It is far better to re-write the for loops properly than to practice bad habits. The OP really should change their for loops.

Edited 6 Years Ago by Fbody: n/a

It looks like you are still not using name[0], and you declared string name[25] which will create locations for name[0], name[1], ... , name[24]. If you create the maximum number of students, the last student will be entered into name[25] which will not exist so your program will break if you try to enter 25 students. You can try it just to be sure, but if you make your declaration string name[26] that should fix the problem instead of having to rewrite your for loops.

kes,

Sorry to respond late, read up more on array and how it works(just the basics for the level of knowledge). Retested my program as you suggested with "24, 25, and 26" names - the program did break at 24 and 25(with name{25}) but not at 26. Thank-you for the insight.

My question though is this if you don't mind me asking - If the count (names) starts at 0,1,2... wouldn't the last name be stored in [24]. what is the logic behind 26?

Would appreciate an explanation for my own knowledge.

Regards.

kes,

Sorry to respond late, read up more on array and how it works(just the basics for the level of knowledge). Retested my program as you suggested with "24, 25, and 26" names - the program did break at 24 and 25(with name{25}) but not at 26. Thank-you for the insight.

My question though is this if you don't mind me asking - If the count (names) starts at 0,1,2... wouldn't the last name be stored in [24]. what is the logic behind 26?

Would appreciate an explanation for my own knowledge.

Regards.

If you define your array with 26 elements, the last index of the array is 25. Essentially all it does is enlarge your array to waste memory and propagate bad technique. As written, your for loops are not correct. They are written to start at 1 and end at ARRAY_SIZE. This is not proper technique for traversing arrays. To properly traverse and access all elements of the array, and not overrun the array's boundaries, they should be written to start at zero (0) and end at (ARRAY_SIZE - 1).

const int ARRAY_SIZE = 10;
int array1[ARRAY_SIZE]  //define an array with ARRAY_SIZE elements

//improper for loop, will cause memory/segmentation errors
for (int i = 1; i <= ARRAY_SIZE; ++i) {
  cout << array1[i] << " "
}

//also improper for loop, will cause memory/segmentation errors
for (int i = 0; i <= ARRAY_SIZE; ++i) {
  cout << array1[i] << " "
}

//proper for loop, will NOT cause memory/segmentation errors
for (int i = 0; i < ARRAY_SIZE; ++i) {
  cout << array1[i] << " "
}

Notice the differences in the way that 'i' is initialized and used in each of the 3 versions. Only the third version is correct.

Edited 6 Years Ago by Fbody: n/a

If you define your array with 26 elements, the last index of the array is 25. Essentially all it does is enlarge your array to waste memory and propagate bad technique. As written, your for loops are not correct. They are written to start at 1 and end at ARRAY_SIZE. This is not proper technique for traversing arrays. To properly traverse and access all elements of the array, and not overrun the array's boundaries, they should be written to start at zero (0) and end at (ARRAY_SIZE - 1).

const int ARRAY_SIZE = 10;
int array1[ARRAY_SIZE]  //define an array with ARRAY_SIZE elements

//improper for loop, will cause memory/segmentation errors
for (int i = 1; i <= ARRAY_SIZE; ++i) {
  cout << array1[i] << " "
}

//also improper for loop, will cause memory/segmentation errors
for (int i = 0; i <= ARRAY_SIZE; ++i) {
  cout << array1[i] << " "
}

//proper for loop, will NOT cause memory/segmentation errors
for (int i = 0; i < ARRAY_SIZE; ++i) {
  cout << array1[i] << " "
}

Notice the differences in the way that 'i' is initialized and used in each of the 3 versions. Only the third version is correct.

Many thanks Fbody, it's all gradually falling in place bit by bit. I will be back with more questions - learning alot more here than in class, it's all so blurry during lectures - for over a month i thought my instructor was saying "naked number" till he wrote it down and it was actually "negate number" .

Regards

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