Searching Program help!

I don't know why I can't find any people's name!
It always says player not found.

Help please!!

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
 #include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>

using namespace std;
const int SIZE = 10;
const int NSIZE = 30;
struct Players
{
    char fname[NSIZE];
    char lname[NSIZE];
    int birthmonth;
    int birthday;
    int birthyear;
};

bool DataInput      (Players[], Players[]);
void DataDisplay    (Players[]);
void bubbleSort     (Players[]);
void PlayerSearch   (Players[]);
int searchName      (Players[], char[]);

int main()
{
    string menu = "1: Input Data \n2: Display Original Data \n";
    menu += "3: Sort Data \n4: Display Sorted Data \n";
    menu += "5: Search by First Name \n6: Quit \n";
    Players originalData[SIZE];
    Players sortedData[SIZE];
    int choice = 0;

    do
    {
        cout << endl;
        cout << menu;
        cin >> choice;
        cout << endl;

        switch (choice)
        {
        case 1:
            if(DataInput(originalData, sortedData))
            {
                cout << "Data have been read.\n\n";
            }
            else
            {
                cout << "Error in reading data" << endl;
                return 1;
            }
            break;
        case 2:
            DataDisplay(originalData);
            break;
        case 3:
            bubbleSort(sortedData);
            break;
        case 4:
            DataDisplay(sortedData);
            break;
        case 5:
            PlayerSearch(sortedData);
            break;
        case 6:
            cout << "Thanks for using my program!";
            break;
        default:
            cout << "Error, enter a valid menu option.";
            break;
        }
        cout << endl;
    }
    while (choice != 6);

    return 0;
}

bool DataInput(Players o[], Players s[])
{
    fstream infile ("Players.txt", ios::in);

    if (!infile)
    {
        cout << "Error. File missing or corrupted. \n";
        return false;
    }
    else
    {
        for (int i = 0; i < SIZE; i++)
        {
            infile >> o[i].fname;
            infile >> o[i].lname;
            infile >> o[i].birthday;
            infile >> o[i].birthmonth;
            infile >> o[i].birthyear;
            s[i] = o[i];
        }
        infile.close();
    }
    cout << "File has been read!";
    return true;
}

void PlayerSearch(Players p[])
{
    char fname[NSIZE];
    int index = -1;

    cout << "Enter the first name to search: (// to quit)";
    cin.ignore();
    cin.getline(fname, NSIZE);
    while (strcmp(fname, "//") != 0)
    {
        index = searchName(p, fname);
        if (index != -1)
        {
            cout << "\nPlayer found:\n";
            cout << left << setw (10) << p[index].fname << " ";
            cout << left << setw (10) << p[index].lname << " ";
            cout << left << p[index].birthmonth << "/";
            cout << left << p[index].birthday << "/";
            cout << left << p[index].birthyear;
            cout << endl;
        }
        else
            cout << "\nPlayer not found!" << endl;
        cout << "Enter the last name to search: ";
        cin.getline(fname, NSIZE);
    }
}

void DataDisplay(Players p[])
{
    cout << left << setw (15) << "FIRST NAME ";
    cout << left << setw (15) << "BIRTH MONTH" << endl;
    cout << left << setw (15) << "BIRTH YEAR" << endl;
    for (int i = 0; i < SIZE; i++)
    {
        cout << left << setw (15)  << p[i].fname;
        cout << left << setw (15)  << p[i].lname;
        cout << left << setw (15)  << p[i].birthmonth;
        cout << left << setw (15)  << p[i].birthday;
        cout << left << setw (15)  << p[i].birthyear;

        cout << endl;
    }
}

int searchName (Players p[], char fname[])
{
    int pos = -1, result;
    for (int i = 0; i < SIZE; i++)
    {
        result = strncmp(p[i].fname, fname, strlen(fname));

        if (result == 0)
        {
            pos = i;
            return pos;
        }
    }
    return pos;
}

void bubbleSort (Players p[])
{
    int pass = 1;
    Players temp;
    bool swap = true;

    while (pass < SIZE && swap == true)
    {
        swap = false;
        for (int i = 0; i < SIZE-1; i++)
        {
            if (strcmp(p[i].fname, p[i+1].fname) > 0)
            {
                temp = p[i];
                p[i] = p[i+1];
                p[i+1] = temp;
                swap = true;
            }
        }
        pass = pass +1;
    }
}
Have you run the program with your debugger? Set a breakpoint early in the program, single step through the program, stepping into functions as you go, and watch your variables and perhaps you can see what is happening.

By the way, I recommend you switch to using std::string and std::vector instead of all those C-strings and arrays.

When encountering these sorts of problems, the first course of action should be to add output statements to see the values of various data pieces involved in your program. However, I think I spot the reason behind your problem.

Line 97 performs an assignment of a Person to another Person. Without overloading the assignment operator, the compiler-made default one does assignment of consecutive members. Your Person type has char[N] as the data type for first and last name, which don't copy contents on assignment. You'll need to write the assignment operator so that it copies all data members + the array elements into the other Person object.

Your searchName function should also store the result of "strlen(fname)" in some local var and then use that within the loop. Currently, strlen() is called repeatedly, and can be expensive. And line 160 should be replaced with a break. There's no need to assign a local var, then return it, just return the i. But sometimes compilers can optimize better if there are no premature returns, hence I suggested a break.

Also PlayerSearch(), DataDisplay(), and searchName() should use const parameters b/c the data is not modified.
closed account (48T7M4Gy)
.
Last edited on
Kemort, you changed the name fields to char* from char[N] and initialize them with dynamically allocated data, but then you reassign them to a string-literal (which should cause an error due the char* being assigned to const char[]) and causes a memory leak. If you want dynamically-allocated strings, you must manually manage the allocations/deallocations/copying chars/etc. yourself and have all the c-tor/d-tor/copy/move c-tor/assignment op functions defined in your Person data type. OR you can use std::string and have it manage all that for you. Clearly the latter is recommended.

However, I do NOT second the idea of using std::string/std::vector in place of cstrings/arrays... at least, not haphazardly. Don't get me wrong those types are great if you actually want the whole package of what they offer, namely the dynamic allocation. But statically-allocated arrays/cstrings are actually more efficient to use, even tho they are more limited. And it's good practice to know the <cstring> functions, at least some the important ones. I DO advise using std::array in place of tradional arrays/cstrings tho!
closed account (48T7M4Gy)
.
Last edited on
Kemort: Nothing I said was intended to be antagonistic, critical, portentous, etc. Strictly pedagogic. And no, I'm no implying YOU didn't know what I said, or "needed approval". I'm just contributing to the topic subject, and yes my content did relate to the subject, if a little circuitously. That's what I've been doing throughout too, so no need to call them "useless paw prints".

You posted some new code that contained errors, and for pedagogy's sake, I pointed it out. Admittedly, I got a little too technical with the first paragraph, so it prolly LOOKED like I was addressing you personally.

The second paragraph *especially* was not directed at you, just the subject matter. So just relax, okay?
closed account (48T7M4Gy)
..
Last edited on
There I go "again"? "Taliban pettiness"? You are hearing a snark in my posts that really and truly is not there.

There's no need to be sarcastic about "errors" either.

This is a learning forum, oriented toward novices. So it makes all the sense in the world to point out errors instead of possibly letting them be absorbed. When you post a block of alternate code and don't document otherwise, it's implied that it's error free. I know you knew that, you're just getting so agitated over this. In the 4th post, I may have used the word "you" too much and that's why you took it personally. I'm sorry, but it *really* was a general statement, pedagogic, not personal.

I too have gotten this far without you... so... *shrugs*

I didn't mean "too technical for you", I meant too much for this forum, or the thread's question in general (I do tend to do that...). That prolly contributed to why you thought I was criticizing you personally.
Thanks guys, please stop fighting. Now I feel bad....

Both of you have been of great help.

EDIT: Sorry for late reply, been quite busy.
Last edited on
closed account (48T7M4Gy)
It's OK super, it's not your fault, your comment is appreciated though. Best wishes as a budding programmer to you. :)
Topic archived. No new replies allowed.