Need help with search/sorting function in Unix

I am completing a practice problem which requests that, using a given txt file, I write a code in unix that gives me a persons information when the user inputs that persons name. I've completed this part and tested it and it seems to work. However, now I'm supposed to make a function that allows the following three steps to be possible: ((I realize this is quite lengthy but am thoroughly lost and any help at how to start this would be much much appreciated!!))

1.
The management wants the youngest person to occupy the first position in the array. Give yourself a function, just like the previous one, that finds the youngest person in the array. Once you know where the youngest person is, you can swap his or her data with the data already occupying the first position in the array. That way nothing is lost. Remember that the first position in an array is numbered zero, not one.
2. Now Promote the Second Youngest.The management has now decided not only that the youngest person must occupy the firstposition in the array, but also that the second-youngest person must occupy the second
position in the array. So, after searching for the youngest and moving their data to the front ofthe array, now search the remainder of the array (all except the first element), and move the youngest person you find (which must be the second youngest of all) into the second position of the array. Make sure you swap data, so that whoever was originally in the second position
is not lost.
3. More of the Same.
The management are going to keep on adding requirements like this, next putting the third youngest in the third position, then the fourth, then the fifth. There is no knowing when they will grow out of this petty obsession, so make things easier for yourself. Modify your search function so that it can be told how much of the array to search. That is, give it two int parameters (let’s call them a and b); its job is now to search only the portion of the array
between position a and position b, to find the youngest person therein. This makes it very easy to search the remainder of the array to find the second and third youngest.

I realize this is quite lengthy but am thoroughly lost and any help at how to start this would be much much appreciated!!

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

struct person
{
        int ssn;
        int dob;
        string fname;
        string lname;
        int zip;
};
void main()
{
        int a;
        int b;
        string c;
        string d;
        int  e;
       
 int const filesize = 1000;
        int const terms = 10;
        person array [1000];
        ifstream fin ("/home/118/people1.txt");
        if(fin.fail())
        {
                cout<<"ERROR";
                exit(1);
        }
        for(int i=0; (i<filesize); i++)
                {
                        fin>>a>>b>>c>>d>>e;
                        if(fin.fail())
                                {
                                        cout<<"ERROR";
                                        exit(1);
                                }
                        array[i].ssn = a;
                        array[i].dob = b;
                        array[i].fname = c;
                        array[i].lname = d;
                        array[i].zip = e;
                }
        fin.close();
        /*
        for(int i=0; (i<terms);i++)
        {
                cout<<aray[i].ssn<<" "<<array[i].dob<<" "<<array[i].fname<<" "<$
        }
        */   
        cout<<"Enter a name *case sensitive* :";
        string Q;
        cin>>Q;
        int i = 0;
        while(i<filesize)
                {
                        if(Q==array[i].fname||Q==array[i].lname)
                {
                        cout<<array[i].ssn<<" "<<array[i].dob<<" <<array[i].fn$
                        i++;
                }
        else i++;
        }
        }
 


You can have a look at the following code, if you want, but that's a complete, even if basic, solution.
So, don't read it if you want to try by your own.

What's asked you is a basic method of sorting the array according to the "dob". You can find a lot of information on internet about it.

A note: please try to add a few smart comments to your code, which should answer the question: "Will I remember what this statement is here for five months hence?". Since I'm not an English native speaker, I had a hard time trying to guess what's a "dob" could be - and I think I've guessed it only because the requirement asked to find the youngest person. I'm still wandering what a "ssn" could be :-/

Anyway, these is my attempt:
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// 1. The management wants the youngest person to occupy the first position
// in the array.
// Give yourself a function, just like the previous one, that finds
// the youngest person in the array.
// Once you know where the youngest person is, you can swap his or her data
// with the data already occupying the first position in the array.
// That way nothing is lost.
// Remember that the first position in an array is numbered zero, not one.

// 2. Now Promote the Second Youngest.
// The management has now decided not only that the youngest person must occupy
// the first position in the array, but also that the second-youngest person
// must occupy the second position in the array.
// So, after searching for the youngest and moving their data to the front
// of the array, now search the remainder of the array
// (all except the first element), and move the youngest person you find
// (which must be the second youngest of all) into the second position
// of the array.
// Make sure you swap data, so that whoever was originally
// in the second position is not lost.

// 3. More of the Same.
// The management are going to keep on adding requirements like this,
// next putting the third youngest in the third position, then the fourth,
// then the fifth.
// There is no knowing when they will grow out of this petty obsession,
// so make things easier for yourself.
// Modify your search function so that it can be told how much of the array
// to search.
// That is, give it two int parameters (let’s call them a and b);
// its job is now to search only the portion of the array between position a
// and position b, to find the youngest person therein.
// This makes it very easy to search the remainder of the array to find
// the second and third youngest.
#include <iostream>
#include <fstream>

using namespace std;

constexpr int MAXPERSONS = 1000;

struct Person
{
    int ssn;
    int dob;
    string fname;
    string lname;
    int zip;
};

// Returns the index of the found person into the array 'persons'
// or -1 if the requested name can't be found.
int findPerson(const Person persons[], int upperbound);

// "...Give yourself a function [...] that finds the youngest person
//  in the array..."
// Returns the index of the youngest person into the array 'persons'
// in the range lowerbound-upperbound.
// It could returns -1 if data into 'persons' are inconsistent.
int findYoungest(Person const persons[], int lowerbound, int upperbound);

void swapPersons(Person persons[], int one, int two);
void printPerson(Person persons[], int index);

int main()
{
    Person persons [MAXPERSONS];
    // I had to change the orginal string to test the program on my system.
    // Original string was: "/home/118/people1.txt".
    ifstream fin("people1.txt");
    if(fin.fail())
    {
        cout<<"ERROR";
        exit(1);
    }

    // Store the entire "people1.txt" file into the array.
    // Count how many records are there.
    int count_persons = 0;
    for(int i = 0; fin; i++)
    {
        fin >> persons[i].ssn >> persons[i].dob >> persons[i].fname
            >> persons[i].lname >> persons[i].zip;
        count_persons++;
    }
    fin.close();

    cout << "\nLet's try to find a person.\n";
    int index = findPerson(persons, count_persons);
    if(index > -1)
    {
        cout << "Found record at position " << index+1 << ": ";
        printPerson(persons, index);
        cout << "\n\n";
    }
    else
    {
        std::cout << "Sorry, the required name is not inside the database.\n\n";
    }

    // Sort persons by year of date
    // Let's keep in mind:
    // "i" will start at 0... that means that we will begin by searching
    //                        from position 0
    // ...but later it will grow to 2, 3, 4... it means that our lower bound
    //                                         will automatically increases
    //                                         i.e. we don't need to care about
    //                                         it.
    for(int i=0; i<count_persons; i++)
    {
        index = findYoungest(persons, i, count_persons);
        // if no errors and this is not already the youngest:
        if(index>-1 && index!=i) {
            swapPersons(persons, index, i);
            cout << "--> Person ";
            printPerson(persons, index);
            cout << "\n--> swapped with person ";
            printPerson(persons, i);
            cout << endl;
        }
    }

    std::cout << "\nNew data are:\n";
    for(int i=0; i<count_persons; i++)
    {
        std::cout << '\n';
        printPerson(persons, i);
        std::cout << '\n';
    }

    return 0;
}

int findPerson(const Person persons[], int upperbound)
{
    cout << "Enter a name *case sensitive*: ";
    string name;
    cin >> name;
    int i = 0;
    while(i<upperbound)
    {
        if(name==persons[i].fname || name==persons[i].lname)
        {
            return i;
        }
        i++;
    }

    /* ...or
    for(int 1; i<upperbound; i++)
        if(name==array[i].fname || name==array[i].lname)
            return i; */

    return -1;
}

void printPerson(Person persons[], int index)
{
    cout << "name: " << persons[index].fname << "; surname: "
         << persons[index].lname << "; ssn: " << persons[index].ssn
         << "; birth date: " << persons[index].dob << "; zip: "
         << persons[index].zip;

}


int findYoungest(Person const persons[], int lowerbound, int upperbound)
{
    int youngest = 0;    // born in year 0 - two thousands years old
    int ret_value = -1;  // acceptable error message, if data were inconsistent
    for(int i=lowerbound; i<upperbound; i++)
    {
        if(persons[i].dob > youngest) // found a younger person
        {
            youngest = persons[i].dob;
            ret_value = i;
        }
    }

    return ret_value; // if errors, it could returns -1
}

void swapPersons(Person persons[], int one, int two)
{
    // Save one of the two person's data
    Person tmp;
    tmp.ssn = persons[one].ssn;
    tmp.dob = persons[one].dob;
    tmp.fname = persons[one].fname;
    tmp.lname = persons[one].lname;
    tmp.zip = persons[one].zip;

    // Overwrite saved person's data
    persons[one].ssn = persons[two].ssn;
    persons[one].dob = persons[two].dob;
    persons[one].fname = persons[two].fname;
    persons[one].lname = persons[two].lname;
    persons[one].zip = persons[two].zip;

    // Overwrite other person with saved data
    persons[two].ssn = tmp.ssn;
    persons[two].dob = tmp.dob;
    persons[two].fname = tmp.fname;
    persons[two].lname = tmp.lname;
    persons[two].zip = tmp.zip;
}

Thank you so much, I tried running this however and it allows me to enter a name, gives me that persons corresponding information but then intstead of proceeding with the rest of the code I get "Segmentation fault (core dumped)
Why would this be happening?
I think because our input files are different.
This is my people1.txt:
1
2
3
4
5
6
7
11 1980 John     Smith    99999
22 1981 Ann      Johnsons 88888
33 1982 Mary     Williams 77777
44 1983 Robert   Brown    66666
55 1979 Patricia Davis    55555
66 1978 Barbara  Miller   44444


If data is written in a different way, it's read and stored in a different way.
If you want, you can copy and paste your people1.txt and I'll test my code on it, but not tomorrow - will be a taught day - I'm also going to my dentist... :-(

Also: maybe "count_persons" grows to much. Try to cout it to check if it's equal to the number of your records.

Anyway, this is my output so far:


Let's try to find a person.
Enter a name *case sensitive*: Williams
Found record at position 3: name: Mary; surname: Williams; ssn: 33; birth date: 1982; zip: 77777

--> Person name: John; surname: Smith; ssn: 11; birth date: 1980; zip: 99999
--> swapped with person name: Robert; surname: Brown; ssn: 44; birth date: 1983; zip: 66666
--> Person name: Ann; surname: Johnsons; ssn: 22; birth date: 1981; zip: 88888
--> swapped with person name: Mary; surname: Williams; ssn: 33; birth date: 1982; zip: 77777

New data are:

name: Robert; surname: Brown; ssn: 44; birth date: 1983; zip: 66666

name: Mary; surname: Williams; ssn: 33; birth date: 1982; zip: 77777

name: Ann; surname: Johnsons; ssn: 22; birth date: 1981; zip: 88888

name: John; surname: Smith; ssn: 11; birth date: 1980; zip: 99999

name: Patricia; surname: Davis; ssn: 55; birth date: 1979; zip: 55555

name: Barbara; surname: Miller; ssn: 66; birth date: 1978; zip: 44444

name: ; surname: ; ssn: 0; birth date: 0; zip: 0

Last edited on
Our input files are in the same format so I don't beleive that's the error. count_persons might be what's crashing but I'm not able to debug it to see where it's crashing. I'm also unable to cout count_persons
.... but I'm not able to debug it to see where it's crashing.


It should be always possible to debug, especially where something crashes :+) Hint: use an actual debugger .... Hopefully there is a GUI version in your IDE. Set up a watch list of variables, set a breakpoint, step through the code one line at a time deduce where things go wrong.
The problem is in reading the file, you read one record too much:

When writing a program it's best to do it in small junks and test immediately.
To test the reading just print it and you see the problem

Code based on Enoizat
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
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

constexpr int MAXPERSONS = 1000;

struct Person
{
  int ssn;
  int dob;
  string fname;
  string lname;
  int zip;
};

void printPerson(Person persons[], int index);

int main()
{
  Person persons[MAXPERSONS];
  // I had to change the orginal string to test the program on my system.
  // Original string was: "/home/118/people1.txt".
  ifstream fin("people1.txt");
  if (fin.fail())
  {
    perror(nullptr);
    system("pause");
    exit(1);
  }

  // Store the entire "people1.txt" file into the array.
  // Count how many records are there.
  int count_persons = 0;
  for (int i = 0; fin; i++)
  {
    fin >> persons[i].ssn >> persons[i].dob >> persons[i].fname
      >> persons[i].lname >> persons[i].zip;
    count_persons++;
  }
  fin.close();

  // Display the data read
  cout << "Number of person: " << count_persons << "\n\n";
  for (int i =0; i < count_persons; i++)
  {
    printPerson(persons, i);
    cout << "\n\n";
  }
  system("pause");
  return 0;
}

void printPerson(Person persons[], int index)
{
  cout << "name: " << persons[index].fname << "; surname: "
    << persons[index].lname << "; ssn: " << persons[index].ssn
    << "; birth date: " << persons[index].dob << "; zip: "
    << persons[index].zip;

}


INPUT

11 1980 John     Smith    99999
22 1981 Ann      Johnsons 88888
33 1982 Mary     Williams 77777
44 1983 Robert   Brown    66666
55 1979 Patricia Davis    55555
66 1978 Barbara  Miller   44444

	

OUTPUT:

Number of person: 7

name: John; surname: Smith; ssn: 11; birth date: 1980; zip: 99999

name: Ann; surname: Johnsons; ssn: 22; birth date: 1981; zip: 88888

name: Mary; surname: Williams; ssn: 33; birth date: 1982; zip: 77777

name: Robert; surname: Brown; ssn: 44; birth date: 1983; zip: 66666

name: Patricia; surname: Davis; ssn: 55; birth date: 1979; zip: 55555

name: Barbara; surname: Miller; ssn: 66; birth date: 1978; zip: 44444

name: ; surname: ; ssn: -858993460; birth date: -858993460; zip: -858993460

Press any key to continue . . .
Hi, Thomas1965.
Thank you for your help, but as far as I can see you didn’t get a “Segmentation fault”.
“persons” has room for one thousand records, do you think DanielleL21’s people1.txt is filled with such a load of data?

Perhaps you are right, but I’m still convinced there’s an inconsistency inside that file. I’d like to control it, but I can appreciate that, being a classified document, it must be kept secret.

However, the segmentation fault error raised after having found the searched person: it means all data, correct or not, were already loaded into memory, doesn’t it? If so, decreasing “count_persons” by one should fix it, do you agree?

I’ve changed:
Person persons [MAXPERSONS];
into
Person persons [MAXPERSONS] = {};
and added the following line:
cout << "Person records: " << --count_persons << '\n';

Besides, I’ve added ‘couts’ at the beginning and the end of functions.
Now, DanielleL21, if you are interested in making my code work, what about giving a try to this new version and report us what’s the output before the segmentation fault?
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <iostream>
#include <fstream>

using namespace std;

constexpr int MAXPERSONS = 1000;

struct Person
{
    int ssn;
    int dob;
    string fname;
    string lname;
    int zip;
};

// Returns the index of the found person into the array 'persons'
// or -1 if the requested name can't be found.
int findPerson(const Person persons[], int upperbound);

// "...Give yourself a function [...] that finds the youngest person
//  in the array..."
// Returns the index of the youngest person into the array 'persons'
// in the range lowerbound-upperbound.
// It could returns -1 if data into 'persons' are inconsistent.
int findYoungest(Person const persons[], int lowerbound, int upperbound);

void swapPersons(Person persons[], int one, int two);
void printPerson(Person persons[], int index);

int main()
{
    Person persons [MAXPERSONS] = {};
    // I had to change the orginal string to test the program on my system.
    // Original string was: "/home/118/people1.txt".
    ifstream fin("people1.txt");
    if(fin.fail())
    {
        cout<<"ERROR";
        exit(1);
    }

    // Store the entire "people1.txt" file into the array.
    // Count how many records are there.
    int count_persons = 0;
    for(int i = 0; fin; i++)
    {
        fin >> persons[i].ssn >> persons[i].dob >> persons[i].fname
            >> persons[i].lname >> persons[i].zip;
        count_persons++;
    }
    cout << "Person records: " << --count_persons << '\n';
    fin.close();

    cout << "\nLet's try to find a person.\n";
    int index = findPerson(persons, count_persons);
    if(index > -1)
    {
        cout << "Found record at position " << index+1 << ": ";
        printPerson(persons, index);
        cout << "\n\n";
    }
    else
    {
        std::cout << "Sorry, the required name is not inside the database.\n\n";
        return 0; // record not present is not an error
    }

    // Sort persons by year of date
    // Let's keep in mind:
    // "i" will start at 0... that means that we will begin by searching
    //                        from position 0
    // ...but later it will grow to 2, 3, 4... it means that our lower bound
    //                                         will automatically increases
    //                                         i.e. we don't need to care about
    //                                         it.
    for(int i=0; i<count_persons; i++)
    {
        index = findYoungest(persons, i, count_persons);
        // if no errors and this is not already the youngest:
        if(index>-1 && index!=i) {
            swapPersons(persons, index, i);
            cout << "About to call \"printPerson()\"\n";
            cout << "--> Person ";
            printPerson(persons, index);
            cout << "\n--> swapped with person ";
            printPerson(persons, i);
            cout << endl;
        }
    }

    std::cout << "\nNew data are:\n";
    for(int i=0; i<count_persons; i++)
    {
        std::cout << '\n';
        printPerson(persons, i);
        std::cout << '\n';
    }

    return 0;
}

int findPerson(const Person persons[], int upperbound)
{
    std::cout << "\nEntering function \"findPerson()\"\n";
    cout << "Enter a name *case sensitive*: ";
    string name;
    cin >> name;
    int i = 0;
    while(i<upperbound)
    {
        if(name==persons[i].fname || name==persons[i].lname)
        {
            std::cout << "\nExiting function \"findPerson()\" returning "
                      << i << '\n';
            return i;
        }
        i++;
    }

    /* ...or
    for(int 1; i<upperbound; i++)
        if(name==array[i].fname || name==array[i].lname)
            return i; */

    std::cout << "\nExiting function \"findPerson()\" returning " << i << '\n';
    return -1;
}

void printPerson(Person persons[], int index)
{
    cout << "name: " << persons[index].fname << "; surname: "
         << persons[index].lname << "; ssn: " << persons[index].ssn
         << "; birth date: " << persons[index].dob << "; zip: "
         << persons[index].zip;

}


int findYoungest(Person const persons[], int lowerbound, int upperbound)
{
    std::cout << "\nEntering function \"findYoungest()\"\n";
    int youngest = 0;    // born in year 0 - two thousands years old
    int ret_value = -1;  // acceptable error message, if data were inconsistent
    for(int i=lowerbound; i<upperbound; i++)
    {
        if(persons[i].dob > youngest) // found a younger person
        {
            youngest = persons[i].dob;
            ret_value = i;
        }
    }

    std::cout << "\nExiting function \"findYoungest()\" returning "
              << ret_value << '\n';
    return ret_value; // if errors, it could returns -1
}

void swapPersons(Person persons[], int one, int two)
{
    std::cout << "\nEntering function \"swapPersons()\"\n";
    // Save one of the two person's data
    Person tmp;
    tmp.ssn = persons[one].ssn;
    tmp.dob = persons[one].dob;
    tmp.fname = persons[one].fname;
    tmp.lname = persons[one].lname;
    tmp.zip = persons[one].zip;

    // Overwrite saved person's data
    persons[one].ssn = persons[two].ssn;
    persons[one].dob = persons[two].dob;
    persons[one].fname = persons[two].fname;
    persons[one].lname = persons[two].lname;
    persons[one].zip = persons[two].zip;

    // Overwrite other person with saved data
    persons[two].ssn = tmp.ssn;
    persons[two].dob = tmp.dob;
    persons[two].fname = tmp.fname;
    persons[two].lname = tmp.lname;
    persons[two].zip = tmp.zip;
    std::cout << "\nExiting function \"swapPersons()\"\n";
}


Otherwise, if you want to make it by your own, don’t matter.
Hi Enoizat,
“persons” has room for one thousand records, do you think DanielleL21’s people1.txt is filled with such a load of data?

Her code from the first post will fail if it has less than 1000 records.
1
2
3
4
5
6
7
8
for(int i=0; (i<filesize); i++)
{
   fin>>a>>b>>c>>d>>e;
   if(fin.fail())
   {
       cout<<"ERROR";
       exit(1);
    }

This would explain the seg fault if you read more than 1000 records.
If so, decreasing “count_persons” by one should fix it, do you agree?

It might fix it but it's not good practice. The actual problem is reading one record too much and that should be fixed.
Her code from the first post will fail if it has less than 1000 records.

@Thomas1965, you can't see me, but I rose and took a bow when I read that. Thank you again.

Hope this code could now work:
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <iostream>
#include <fstream>

using namespace std;

constexpr int MAXPERSONS = 1000;

struct Person
{
    int ssn;
    int dob;
    string fname;
    string lname;
    int zip;
};

// Returns the index of the found person into the array 'persons'
// or -1 if the requested name can't be found.
int findPerson(const Person persons[], int upperbound);

// "...Give yourself a function [...] that finds the youngest person
//  in the array..."
// Returns the index of the youngest person into the array 'persons'
// in the range lowerbound-upperbound.
// It could returns -1 if data into 'persons' are inconsistent.
int findYoungest(Person const persons[], int lowerbound, int upperbound);

void swapPersons(Person persons[], int one, int two);
void printPerson(Person persons[], int index);

int main()
{
    Person persons [MAXPERSONS] = {};
    // I had to change the orginal string to test the program on my system.
    // Original string was: "/home/118/people1.txt".
    ifstream fin("people1.txt");
    if(fin.fail())
    {
        cout<<"ERROR";
        exit(1);
    }

    // Store the entire "people1.txt" file into the array.
    // Count how many records are there.
    int count_persons = 0;
    while(fin >> persons[count_persons].ssn >> persons[count_persons].dob
              >> persons[count_persons].fname >> persons[count_persons].lname
              >> persons[count_persons].zip)
    {
            count_persons++;
    }
    cout << "Person records: " << count_persons << '\n';
    fin.close();

    cout << "\nLet's try to find a person.\n";
    int index = findPerson(persons, count_persons);
    if(index > -1)
    {
        cout << "Found record at position " << index+1 << ": ";
        printPerson(persons, index);
        cout << "\n\n";
    }
    else
    {
        std::cout << "Sorry, the required name is not inside the database.\n\n";
        return 0; // record not present is not an error
    }

    // Sort persons by year of date
    // Let's keep in mind:
    // "i" will start at 0... that means that we will begin by searching
    //                        from position 0
    // ...but later it will grow to 2, 3, 4... it means that our lower bound
    //                                         will automatically increases
    //                                         i.e. we don't need to care about
    //                                         it.
    for(int i=0; i<count_persons; i++)
    {
        index = findYoungest(persons, i, count_persons);
        // if no errors and this is not already the youngest:
        if(index>-1 && index!=i) {
            swapPersons(persons, index, i);
            cout << "--> Person ";
            printPerson(persons, index);
            cout << "\n--> swapped with person ";
            printPerson(persons, i);
            cout << endl;
        }
    }

    cout << "\nNew data are:\n";
    for(int i=0; i<count_persons; i++)
    {
        cout << '\n';
        printPerson(persons, i);
        cout << '\n';
    }

    return 0;
}

int findPerson(const Person persons[], int upperbound)
{
    cout << "Enter a name *case sensitive*: ";
    string name;
    cin >> name;
    int i = 0;
    while(i<upperbound)
    {
        if(name==persons[i].fname || name==persons[i].lname)
        {
            return i;
        }
        i++;
    }

    /* ...or
    for(int 1; i<upperbound; i++)
        if(name==array[i].fname || name==array[i].lname)
            return i; */

    return -1;
}

void printPerson(Person persons[], int index)
{
    cout << "name: " << persons[index].fname << "; surname: "
         << persons[index].lname << "; ssn: " << persons[index].ssn
         << "; birth date: " << persons[index].dob << "; zip: "
         << persons[index].zip;

}


int findYoungest(Person const persons[], int lowerbound, int upperbound)
{
    int youngest = 0;    // born in year 0 - two thousands years old
    int ret_value = -1;  // acceptable error message, if data were inconsistent
    for(int i=lowerbound; i<upperbound; i++)
    {
        if(persons[i].dob > youngest) // found a younger person
        {
            youngest = persons[i].dob;
            ret_value = i;
        }
    }

    return ret_value; // if errors, it could returns -1
}

void swapPersons(Person persons[], int one, int two)
{
    // Save one of the two person's data
    Person tmp;
    tmp.ssn = persons[one].ssn;
    tmp.dob = persons[one].dob;
    tmp.fname = persons[one].fname;
    tmp.lname = persons[one].lname;
    tmp.zip = persons[one].zip;

    // Overwrite saved person's data
    persons[one].ssn = persons[two].ssn;
    persons[one].dob = persons[two].dob;
    persons[one].fname = persons[two].fname;
    persons[one].lname = persons[two].lname;
    persons[one].zip = persons[two].zip;

    // Overwrite other person with saved data
    persons[two].ssn = tmp.ssn;
    persons[two].dob = tmp.dob;
    persons[two].fname = tmp.fname;
    persons[two].lname = tmp.lname;
    persons[two].zip = tmp.zip;
}

Last edited on
@Thomas1965, you can't see me, but I rose and took a bow when I read that. Thank you again.

@Enoizat,
you are very welcome. Everything seems to work now.
BTW: I think the swap function can be simplified.
1
2
3
4
5
6
void swapPersons(Person persons[], int one, int two)
{
  Person tmp = persons[one];
  persons[one] = persons[two];
  persons[two] = tmp;
}
It looks a great improvement to me, @Thomas1965.
Before writing my version, I had read into the requirements "...swap his or her data with the data already occupying the first position...", "...moving their data...", "...Make sure you swap data...", so I convinced myself that was the way it had to be done.
But now I think you are right and I misunderstood the text.
Topic archived. No new replies allowed.