Невозможно вернуть значение структуры в c ++ - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть два текстовых файла, и Load function переносит данные из обоих текстовых файлов в одну структуру (Employee emp[length]) с длиной константы 2001. Это потому, что в текстовом файле содержится 2000 сведений о сотрудниках.

После загрузки данных в структуру я захотел найти и отобразить данные о сотруднике с помощью функции Выбрать.

Пользователю будет предложено выбрать атрибут сотрудника и ключевое слово, которое будет использоваться для поиск. Однако я понимаю, что не могу вернуть struct(emp[i]) или строковое значение (emp[i].empId). Он выдаст сообщение об ошибке:

место чтения нарушения доступа 0x00D2C000

Однако я могу отобразить строковое значение (emp[i].empId), используя cout.

Могу ли я узнать, почему я могу cout строковое значение, но не вернуть его?

Заранее благодарю за помощь и извините за бедного Энгли sh.

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();
}

1 Ответ

0 голосов
/ 03 апреля 2020

Основная проблема, я думаю, что вы возвращаете, если Select ничего не находит? Функция должна возвращать сотрудника. У вас может быть специальный Employee с бессмысленным empId (например, -1), чтобы указать это, и изменить

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

на

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

В качестве альтернативы вы можете изменить Функция Select возвращает указатель Employee *, а затем возвращает nullptr, если совпадения нет. Это

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
}

Затем следует

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
    }
}

На самом деле вы, вероятно, захотите вернуть const Employee const*, но это еще одна топи c.

Еще один вариант - Select генерировать исключение, если оно ничего не находит, и помещать вызов на Select(search, key, i); в блоке try .. catch. Я обычно предпочитаю не использовать исключения для потока управления, как это, но это другой метод.

...