Sorting? Or Searching

Pages: 123... 7
So this is my code up until now. I want to put in a search option however I don't know what type of search is the most efficient and no clue how to implement. Can someone point me in the right direction.

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
	#include <iostream> 
	#include <string>
	#include <math.h> 
	#include <fstream>
	using namespace std;

class Details
{
public:
    Details(); 
    string FirstName;
    string LastName;
    int Age ;
    string Email;
    int DoorNumber;
    string RoadName;
    string PostCode;
	
};

	 Details::Details() : Age(0), DoorNumber(0) {}
void DataEntry(Details &member){
	cout << "First Name: ";
    cin >> member.FirstName;

    cout << "Last Name: ";
    cin >> member.LastName;

	cout << "Age: ";
    cin >> member.Age;

	cout << "Email: ";
    cin >> member.Email;

    cout << "Door Number: ";
    cin >> member.DoorNumber;

    cout << "Road Name: ";
    cin >> member.RoadName;

    cout << "Post Code: ";
    cin >> member.PostCode;
}
void GetData(Details &member){
	cout << "\nFirst Name: "<< member.FirstName;
	cout << "\nLast Name: " << member.LastName;
	cout << "\nAge: " << member.Age;
	cout << "\nEmail: " << member.Email;
	cout << "\nDoor Number: " <<  member.DoorNumber;
	cout << "\nRoad Name: " << member.RoadName;
	cout << "\nPost Code: " <<  member.PostCode;
}
int main()
{	int i;
	int a;
	a=0;
	Details	info[10];		
	
	do{	
		cout << "\n1) Input \n2) View \n3) Delete\n4) Exit \n" ;
		cin >> a;
		switch(a){
			  case 1:	
				//Input;
				cout << "\nWhich Slot would you like to store the informaton in ?(0-9)";
				cin >> i;
				DataEntry(info[i]); break;
			  case 2: 
				//View;
				cout << "Would You like to view the data?";
				cin >> i;
				GetData(info[i]);	break;
			  case 3: 
				//Delete;
									break;
			  case 4: 
				//Exit;
									break;
			  default: break;       
		   }
	}
	while(a!=4);


return 0;}
Not a comment on the code, but on the design.
In real addresses, DoorNumber may be the name of a house or building, thus it should probably be a string. But for an example program it probably doesn't matter.
What are your search criteria going to be?

None of your fields appear to be unique, although it's possible that a combination of fields (post code, road name, door number) should be unique.

You have a number of choices.
1) With only 10 entries, a simple linear search will work just fine.
2) Use the STL <map> container. Since you don't have a unique field, you would have to write your own comparison routine.

Given the code you've posted so far, you need a way to track whether a slot has been used. What happens if you try to view a slot that has not been entered?
what do you mean they should be unique?

and im going to do that later I just don't know where to start with the search
if you try to view a slot that's empty it comes up as empty?
closed account (D80DSL3A)
Searching should be easy now that you are using a class to contain the Details.

You do need a way to tell if an info has been used. You could test for age = 0.
Here's an example of searching by age:
1
2
3
4
5
6
7
int age_to_find = 0;
cout << "Enter an age: "; cin >> age_to_find;
for(int i=0; i < 10; ++i)// look through all elements
{
    if( info[i].age == age_to_find )
        cout << info[i].FirstName << " "  info[i].LastName << " is" << info[i].age << " years old." << endl;
}

Line 5 determines the search criteria (which member is being searched by).
As another example, you could list everyone in a given post code with this:
1
2
3
4
5
6
7
string PostCode_to_find;
cout << "Enter a postal code: "; cin >> PostCode_to_find;
for(int i=0; i < 10; ++i)// look through all elements
{
    if( info[i].PostCode == PostCode_to_find )
        cout << info[i].FirstName << " "  info[i].LastName << " lives in postal code " << info[i].PostCode << endl;
}

Note that unused "slots" will be passed over because the tests are never satisfied.
ok will try that
Last edited on
It doesn't make sense to have the search function be a method since the class represents a single entry, not a list of them, and you can't search a single entry in any useful way.
its not a single entry. ? or what do you mean by entry?
closed account (D80DSL3A)
Your Details class is a "blue print" for what a single Detail object is.
It isn't really sensible for an object to contain an array of itselves.

I would go back to using the array of Details in main() like you had before.
What you can do is to write the search function as a regular global function, which searches through an array of Detail objects.

Returning to your previous definition of the Detail class:
1
2
3
4
5
6
7
8
9
10
11
12
class Details
{
public:
    Details(); 
    string FirstName;
    string LastName;
    int Age ;
    string Email;
    int DoorNumber;
    string RoadName;
    string PostCode;	
};

You could make a global function:
1
2
3
4
5
6
7
8
void searchByAge( Detail D[], int size )
{
    int AgeSearch = 0;
	cout << "Enter an age: "; cin >> AgeSearch;
	for(int i=0; i < size; ++i){
    if( D[i].age == AgeSearch )
        cout << D[i].FirstName << " "  D[i].LastName << " is" << D[i].Age << " years old." << endl;
}

The setup in main goes back to what you had with Details info[10] declared there.
1
2
3
4
5
6
7
int main()
{
    Details info[10];
    // your code for filling the info elements with data.
    cout << "Searching by age..." << endl;
    searchByAge( info, 10 );
}


EDIT: Your DataEntry() and GetData() functions operate on a single Detail object, so these would make suitable Detail class member functions.
Last edited on
Im going to try that as my code in main is getting rather large as I have loads of different search options now. Thanks again for your help. Need to learn how to save to text file now. Also why is D[] instead of info?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
void LastName_Search(Details info[],int size){
	string LastNameSearch;
	cin >> LastNameSearch;
	for(int i=0; i < size; i++){
		if( info[i].LastName == LastNameSearch ){
		cout << "Here are Details of People who have the Surname "<< LastNameSearch<<":";
		GetData(info[i]);
		}
	}

}


For this bit of code I keep getting the error on line 3 last name search is undefined?

its a string do I have to define it?
closed account (D80DSL3A)
Also why is D[] instead of info?

The info[10] array is local to the main(), it is not global. The LastName_Search() function knows nothing about the info[10] array. It is not in scope within the function.

LastName_Search() only knows of the array passed to it as the 1st parameter in the function call. The name is determined by what appears in the function definition, which I chose to be D.
It is OK to use the name info for the array in the LastName_Search(), but I would consider this to be inviting confusion.

Im going to try that as my code in main is getting rather large as I have loads of different search options now.

So, it may be time to split some of that up into functions too.

I don't see anything wrong with the code in your last post. What is the actual error message?
Just been looking at fstream I don't understand do I need to call the method everytime I want to save something to a file ? because I want to be able to save so I can pull up the records from a file? Don't have a clue how to do this.

Also thanks a lot for explaining A lot of people just show me a piece of code with everything already done. And I have no idea whats going on. Your way makes sense so I can use it later.
Last edited on
closed account (D80DSL3A)
You're welcome. I'm glad to see you are picking up on all this so well.

A little more about the array naming issue. I thought of a way to show it clearly.
The search() functions you have are written to work with any array of Details that is passed to it.
Suppose you write a program where several arrays of Details are needed because you are categorizing people (for example). You would be able to use each search() function on any array since the name passed doesn't matter.
Example:
1
2
3
4
5
6
7
8
9
10
int main()
{
    Details Students[20];
    Details Employees[15];
    Details Pensioners[50];
    //...
    LastName_Search(Students,20);// among students
    LastName_Search(Employees,15);// among employees
    LastName_Search(Pensioners,50);// among pensioners
}

All 3 of these arrays are known as 'info' in the function.

I would advise trying the file I/O on a simpler task first, since this is a first time for you.
Try just reading and writing an array of 10 integers from/to files.
Last edited on
yea I understood what you meant before I should have separate names so I know where its coming from. Because the codes small now it shouldn't matter but when its bigger it will get more complicated.

I know when I say it doesn't seem like I understand but I do xD.

by I/o do you mean in put output if so are there any good tutorials for this? ive read the one on cplusplus I don't really understand it.

especially the wordings these tutorials use.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 #include <fstream>
#include <iostream>
using namespace std;

int main(){
	int Array[10];
	 for(int i=0; i<10; i++)
	 {Array[i]=10+i;
	 }
	
	
	ofstream fout("array.txt");

	 for(int i=0; i<10; i++){
	 fout << Array[i] << endl;
	 cout << Array[i];
	 fout.close();}


	 cin.get();

	return 0;}



tried It but when It saves to file it only saves 10?
closed account (D80DSL3A)
I'm not aware of any especially good tutorials on file I/O (input/output), so maybe search off site.
I searched for "text file I/O" on this site and found a thread which gives some basics:
http://www.cplusplus.com/forum/general/78167/#msg421073

The file I/O really doesn't need to be much more complicated than this:
1
2
3
4
5
6
7
8
9
10
ifstream myfile ("example.txt");
if (myfile.is_open())
{
	int value;
	while (myfile >> value)
	{
		cout << value << endl;
	}
}
else cout << "Unable to open file";

That code is written to read every integer value from "example.txt" and echo the values to the console (cout << value << endl;) so success can be seen.

Your task is not much harder. Generalizing from the above code to read values into an array (passed as info with size given, like in your search functions):
1
2
3
4
5
6
7
8
9
10
11
12
ifstream myfile ("example.txt");
if (myfile.is_open())
{
	int i = 0;
	while ((i < size) && (myfile >> info[i]))
	{
		cout << info[i] << " " << endl;
                i = i + 1;
	}
        myfile.close();// close the file when finished reading from it
}
else cout << "Unable to open file";

This code would read values until they run out (there are less than size values in the file) or until i = size, when it just stops reading.

If you get that working for integers then I'll help you generalize it so that it is reading Details objects from the file, instead of integers.
Last edited on
what do you mean by generalize?

and what is happening here.

myfile >> value

?
Last edited on
closed account (D80DSL3A)
That represents an integer flowing from a file into value, same as
cin >> value; reads an integer from the console (user input).

By generalize I mean overloading operator >> for a Details object so that
myfile >> info[i] means read a Details object from the file.
The function for operator >> would be written similar to your existing GetData() function, except without the user prompts (no cout statements).
Pages: 123... 7