0

I have two text files and the Load function transfers the data from both text files to a single struct (Employee emp[length]) with a const length of 2001. This is because there are 2000 employee details in the text file.

After loading the data into struct, I wanted to search and display employee data using the Select function.

The user will be prompted to choose which employee attribute and keyword that is going to be used for searching. However, I realize that I cannot return a struct(emp[i]) or a string value(emp[i].empId). It will prompt out an error saying

access violation reading location 0x00D2C000

However, I am able to display the string value(emp[i].empId) using cout.

May I know why can I cout the string value but not return it?

Thank you for your help in advance and sorry for my poor English.

const int length = 2001;

struct Employee {
string empId;
string dOB;
string height;
string weight;
string yrOfWork;
string salary;
string allowance;
string name;
string country;
string designation;
string gender;
string lvlOfEdu;
};

Employee emp[length];

void Load();
Employee Select(int k, string s, int c);


int main() {
bool quit = false;
int option;

while (quit != true) { //loop the program unless 7 is chosen
    Load();

    cout << "1. Add" << endl; //
    cout << "2. Delete" << endl;
    cout << "3. Select" << endl;
    cout << "4. Advanced Search" << endl;
    cout << "5. Standard Deviation" << endl;
    cout << "6. Average" << endl;
    cout << "7. Quit" << endl;

    cout << "Please key in an option: ";
    cin >> option;
    system("cls"); //to refresh the screen

    switch (option) {
    case 3: {
        int search;
        string key;

        cout << "1.  Employee ID" << endl;
        cout << "2.  Date of Birth" << endl;
        cout << "3.  Height" << endl;
        cout << "4.  Weight" << endl;
        cout << "5.  Years of Working" << endl;
        cout << "6.  Basic Salary" << endl;
        cout << "7.  Allowance" << endl;
        cout << "8.  Employee Name" << endl;
        cout << "9.  Country" << endl;
        cout << "10. Designation" << endl;
        cout << "11. Gender" << endl;
        cout << "12. Level of Education" << endl;

        cout << "Select By: ";
        cin >> search;
        cout << "Enter keyword: ";
        cin >> key;

        for (int i = 0; i < length; i++) {
            cout << Select(search, key, i).empId;
        }

        system("pause");
        system("cls");
        break;
        }
    }
}
}

Employee Select(int s, string k, int c) {
int result;
int i = c;

switch(s) {
case 1:

    result = emp[i].empId.find(k);
    if (result >= 0) {
        return emp[i];
    }

    break;
}
}

void Load() {
ifstream inFigures;
inFigures.open("profiles_figures.txt");
ifstream inWords;
inWords.open("profiles_words.txt");

if (inFigures.is_open()) {
    int i = 0;
    while (!inFigures.eof()) {

        inFigures >> emp[i].empId;
        inFigures.ignore();
        inFigures >> emp[i].dOB;
        inFigures.ignore();
        inFigures >> emp[i].height;
        inFigures.ignore();
        inFigures >> emp[i].weight;
        inFigures.ignore();
        inFigures >> emp[i].yrOfWork;
        inFigures.ignore();
        inFigures >> emp[i].salary;
        inFigures.ignore();
        inFigures >> emp[i].allowance;
        inFigures.ignore();
        i++;
    }
}
//inFigures.close();

if (inWords.is_open()) {
    int i = 0;
    while (!inWords.eof()) {

        getline(inWords, emp[i].name);
        getline(inWords, emp[i].country);
        getline(inWords, emp[i].designation);
        inWords >> emp[i].gender;
        inWords.ignore();
        inWords >> emp[i].lvlOfEdu;
        inWords.ignore();
        i++;
    }
}
//inWords.close();
}
Sohail Aslam
  • 727
  • 4
  • 24
  • 1) Please provide the input you used. What, do you think, your `Select` function returns if `s != 1`, or `result < 0`? 2) Aditionally, the reasoning of "_with a const length of 2001. This is because there are 2000 employee details in the text file." doesn't make sense. If there are exactly 2000` employee records in a file, the array of `2000` would suffice. The reason for possible issues, you might face is the [`inWords.eof ()` you are using](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) when reading the file. – Algirdas Preidžius Apr 03 '20 at 10:18
  • You don't need an extra element for arrays. I think you're confusing "C string" arrays with arrays in general. – molbdnilo Apr 03 '20 at 10:40

1 Answers1

0

The main problem I think is, what do you return if Select doesn't find anything? The function is supposed to return an employee. You could have a special Employee with a nonsensical empId (e.g. -1) to indicate this, and change

for (int i = 0; i < length; i++)
{
    cout << Select(search, key, i).empId;
}

to

for (int i = 0; i < length; i++)
{
    Employee selected = Select(search, key, i);
    if (selected.empId != -1)
    {
        cout << Select(search, key, i).empId;
    }
}

Alternatively you could alter the Select function so that it returns a pointer Employee * and then return nullptr if there is no match. That is

Employee* Select(int s, string k, int c)
{
    int result;
    int i = c;   // why not just use c directly? Or change the argument to int i?

    switch(s)
    {
    case 1:

        result = emp[i].empId.find(k);
        if (result >= 0)
        {
             return &emp[i]; // note taking address, could also write emp + i
        }

        break;   // don't need this with no further cases
     }

     return nullptr; // reached if no match above
}

Followed later by

for (int i = 0; i < length; i++)
{
    Employee* selected = Select(search, key, i);
    if (selected != nullptr)
    {
        cout << Select(search, key, i)->empId;  // not pointer indirection
    }
}

Really you'd probably want to return a const Employee const*, but that's another topic.

Yet another option is having Select throw an exception if it doesn't find anything, and placing the call to Select(search, key, i); in a try .. catch block. I generally prefer not to use exceptions for control flow like this, but it is another method.

ChrisD
  • 927
  • 4
  • 10
  • Hi, I managed to solve the problem by using your first method. However, the process of searching takes quite some time which is around 2 minutes. Is it consider a normal time range for a program to loop through 2000 set of data? – Chuah Efu Apr 03 '20 at 11:38
  • No, that sounds extremely slow. – ChrisD Apr 03 '20 at 11:43
  • Is there a possible solution to this? – Chuah Efu Apr 03 '20 at 12:37
  • Hi just an update here. Turns out that I had accidentally inserted the Load function inside my Select function. The problem is solved by just deleting the Load function from the Select function. – Chuah Efu Apr 03 '20 at 12:43