Employee Program: Bizarre error with 'if' statement

Hello :)

I have written a program that stores employees in a database object. You can Add, hire, fire, promote, demote, and display employees. The program uses an interface, a database class, and an employee class with member functions.

The strange behavior is in my switch statement in interface.cpp. I have a '#' that represents a command line. Add and Display functions are ok, but if I hire, fire, promote or demote. It will display '##' for the next input. I ran the debugger and after hire/fire/promote/demote is called, the first if-statement goes to 'else' and I'm trying to figure out why.

Note: main() calls mainMenu() to run the program

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
// interface.cpp
#include <iostream>
#include "database.h"
#include "display.h"
void mainMenu()
{
    displayMenu();
    Database* employeeDatabase = new Database();
    std::string s = "";
    char c;
    while(c != 'Q')
    {
        s = "";
        std::cout << "#";
        
        getline(std::cin, s);
        if(s.length() == 1)
            c = toupper(s[0]);
        else
            c = '?';
        switch(c)
        {
        case 'N':
            employeeDatabase->addEmployee();
            break;
        case 'H':
            employeeDatabase->hireEmployee();
            break;
        case 'F':
            employeeDatabase->fireEmployee();
            break;
        case 'P':
            employeeDatabase->promoteEmployee();
            break;
        case 'D':
            employeeDatabase->demoteEmployee();
            break;
        case 'V':
            employeeDatabase->displayEmployees();
            break;
        case 'Q':
            break;
        }
    }
}


Here are the two classes...

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
// database.cpp
#include <iostream>
#include <vector>
#include <memory>
#include "employee.h"
#include "database.h"
using namespace std;

Database::Database(){}

Employee Database::addEmployee()
{
    Employee e;
    string f;
    string l;
    cout << "Enter first name: ";
    getline(cin, f);
    cout << "Enter last name: ";
    getline(cin, l);
    e.setFirstName(f);
    e.setLastName(l);
    e.setID(idCurrentNumber++);
    myVector.push_back(e);
    cout << "Employee added!" << endl;
    return e;
}

Employee* Database::findEmployee()
{
    int id;
    cout << "Please enter ID Number for the employee: "
         << endl;
    cin >> id;
    for(auto& findId : myVector)
    {
        if (findId.getID() == id)
        {
            pE = &findId;
            return pE;
        }
    }
    cout << "Employee not found!" << endl;
    pE = nullptr;
    return pE;
}

void Database::hireEmployee()
{
    pE = findEmployee();
    if(pE)
        pE->hire();
}

void Database::fireEmployee()
{
    pE = findEmployee();
    if(pE)
        pE->fire();
}

void Database::promoteEmployee()
{
    pE = findEmployee();
    if(pE)
        pE->promote();
}

void Database::demoteEmployee()
{
    pE = findEmployee();
    if(pE)
        pE->demote();
}

void Database::displayEmployees()
{
    for(auto& view : myVector)
    {
        view.displayInfo();
    }
}


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
// employee.cpp
#include <iostream>
#include "employee.h"
using namespace std;

// constructor for employee
Employee::Employee() :  firstName("John"), lastName("Doe"), eNumber(-1), eSalary(0), eHired(false)
{
    maxSalary = defaultSalary;
}

void Employee::displayInfo()
{
    cout     << "\nName: " << getFirstName() << " "
             << getLastName() << endl;
    cout     << "Employee ID: " << getID() << endl;
    cout     << "Hired: ";
    if(eHired)
        cout << "Yes"      << endl;
    else
        cout << "No"       << endl;
    cout     << "Salary: " << getSalary()    << endl;
}

void Employee::setFirstName(const string& f)
{
    firstName = f;
}

const string& Employee::getFirstName()
{
    return firstName;
}

void Employee::setLastName(const string& l)
{
    lastName = l;
}

const string& Employee::getLastName()
{
    return lastName;
}

void Employee::setID(int id)
{
    eNumber = id;
}

const int& Employee::getID()
{
    return eNumber;
}

void Employee::promote(int raise)
{
    if(eHired)
    {
    eSalary += raise;
    maxSalary += raise;
    cout << firstName << " " << lastName <<" has been promoted."
         << "\nand has been given a $" << raise << " raise." << endl;
    }
    else
        cout << "Sorry. Cannot promote non-employees." << endl;

}

void Employee::demote(int cut)
{
    if(!eHired)
    {
         cout << "Sorry, cannot demote non-employees." << endl;
         return;
    }
    if(eHired && eSalary > 10000)
    {
    eSalary -= cut;
    maxSalary -= cut;
    cout << firstName << " " << lastName <<" has been demoted."
         << "\nand has had $" << cut << " cut from salary." << endl;
    }
    else
        cout << "Sorry. Cannot cut salary below $10,000." << endl;
}

void Employee::hire()
{
    if(!eHired)
    {
    eHired = true;
    eSalary = maxSalary;
    cout << firstName << " " << lastName <<" is hired!" << endl;
    }
else
    cout << "Employee is already hired!" << endl;
}

void Employee::fire()
{
    if(eHired)
    {
    eHired = false;
    eSalary = 0;
    cout << firstName << " " << lastName <<" is fired!" << endl;
    }
    else
        cout << "Cannot fire. Employee is not currently employed."
             << endl;
}

const bool& Employee::getHiredStatus()
{
    return eHired;
}

const int& Employee::getSalary()
{
    return eSalary;
}


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
// database.h
#ifndef DATABASE_H_INCLUDED
#define DATABASE_H_INCLUDED

#include "employee.h"
#include <vector>

class Database
{
public:
    Database();
    Employee addEmployee();
    Employee* findEmployee();
    void hireEmployee();
    void fireEmployee();
    void promoteEmployee();
    void demoteEmployee();
    void displayEmployees();

private:
    std::string f;
    std::string l;
    int id;

    const int idStartingNumber = 1000;
    int idCurrentNumber = idStartingNumber;
    std::vector<Employee> myVector;
    Employee* pE = nullptr;
};

#endif // DATABASE_H_INCLUDED 


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
// employee.h
#ifndef EMPLOYEE_H_INCLUDED
#define EMPLOYEE_H_INCLUDED

class Employee
{
public:
    Employee();
    void displayInfo();

    void setFirstName(const std::string& f);
    const std::string& getFirstName();

    void setLastName(const std::string& l);
    const std::string& getLastName();

    void setID(int id);
    const int& getID();

    void promote(int raise = 10000);
    void demote(int cut = 10000);
    void hire();
    void fire();

    const bool& getHiredStatus();
    const int& getSalary();

private:
    std::string firstName;
    std::string lastName;
    int  eNumber;
    int eSalary;
    const int defaultSalary = 30000;
    int maxSalary;
    bool eHired;
};

#endif // EMPLOYEE_H_INCLUDED 


1
2
3
4
5
6
7
// interface.h
#ifndef INTERFACE_H_INCLUDED
#define INTERFACE_H_INCLUDED

void mainMenu();

#endif // INTERFACE_H_INCLUDED 


Last edited on
can you please show your header files?
*added header files*
That happens because you're mixing taking input with std::getline() and with operator>>() overloads. The overloads pop characters from the input buffer until they find whitespace (' ', '\t', '\n'), but don't pop the whitespace itself. So if you type in, say, "george\n", after getting the input with operator>>(), the input buffer will contain "\n". If after that you use std::getline() to get the input, the function will treat that trailing newline as if it had just been typed in, and will simply store an empty string into the std::string.

Luckily, you're only using operator>>() in one place, so the solution is simple:
1
2
3
4
5
6
7
8
9
10
int id;
cout << "Please enter ID Number for the employee: "
     << endl;
//cin >> id;
{
    std::string templine;
    std::getline(std::cin, templine);
    std::stringstream tempstream(templine);
    tempstream >> id; 
}
Personally, I prefer to never use operator>>() with stdin. Its behavior is IMO a breach of the Principle of Least Astonishment.
LOL, "Principle of Least Astonishment"

Never even heard that one before. Very nice concept though.
Thank you helios for your reply! I will try this code today.

Honestly though, is this a sloppy solution for bad coding on my part? In other words, was there a more professional approach I should have taken initially to avoid this problem?
Last edited on
who knows? probably, but its not worth doing unless its necessary.
Topic archived. No new replies allowed.