Using Iterators and STL in C++

Write your question here.
Write your question here.
I am having a hard time understanding what I am doing wrong in this program
and was just wondering if someone could give me some pointers.

I am making a program for extra credit it has to do with dealing with using iterators and STL correctly with functions.
My instructions were:

Declare a structure called Employee with appropriate member variables and read the file contents into member variables of the Employee structure. Create a STL list of the structure.

Design functions for the following purposes

1. Removing any entry by ID specified by the user

2. List the data of the employees with the last name starting with a character provided by the user

It works for removing an entry by the ID but when trying to only print the entries of the user Selected Character of the last name it will not work correctly. I am assuming there is something wrong with my if statement for it but I do not know why My logic is wrong or maybe it is my syntax. This is my first time asking a question on here and it seems I can't even so the preview of my question correctly lol.
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
#include <iostream>
#include <list>
#include <fstream>
#include <string>
using namespace std;

struct Employee
{
        string fname;
        string lname;
        long int ID;
        double salary;
};

// Function to erase user entry and
void erased_entry(list<Employee>& newinfo, long int IDERASED,EmployeeF,char charentry);

int main()
{
        // Declared variables
        list<Employee> info;
        Employee E;
        string fname,lname;
        long int ID, ID2;
        char first_char;
        double salary;
        ifstream in_file;
        // Open text file
        in_file.open("test.txt");

        while(in_file>>fname>>lname>>ID>>salary)
        {
                E.fname=fname;
                E.lname=lname;
                E.ID=ID;
                E.salary=salary;
                info.push_back(E);
        }
        // Initializing iterator and seeding it to the front
        list<Employee>::iterator iter=info.begin();
        // Print out list
        for(iter=info.begin();iter!=info.end();iter++)
        {
                E=*iter;
                cout<<E.fname<<" "<<E.lname<<" "<<E.ID<<" "<<E.salary<<endl;
        }
        // Prompt User for Removing entry by ID and List of Data by a character       by the user 
        cout << "Please indicate an ID to be removed:";
        cin >> ID2;
        ID = ID2;
        cout << endl;
        cout << "Please indicate what employees you would like to see with a character:";
        cin >>  first_char;
        cout << endl;

        //Call functions here
        erased_entry(info,ID,E,first_char);

        //Close test.txt
        in_file.close();
        return 0;
}

void erased_entry(list<Employee>& newinfo, long int IDERASED, Employee F,char charentry)
{
        list<Employee>::iterator iter=newinfo.begin();

        for(iter=newinfo.begin();iter!=newinfo.end();iter++)
       {


                if(iter->ID = IDERASED)
                      iter=newinfo.erase(iter);

                if(iter->lname.at(0) != charentry)
                        iter=newinfo.erase(iter);
                F=*iter;
                cout << F.fname << " " << F.lname << " " << F.ID << " " <<       F.salary << endl;
        }

}
 
On line 72 you are using = (assignment) when what you really want is == (equality comparison).
> Design functions for the following purposes
> 1. Removing any entry by ID specified by the user
> 2. List the data of the employees with the last name starting with a character provided by the user

These are two different functions;
one to erase an entry, given the id,
another to list all entries with the last name starting with the given character.

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
#include <iostream>
#include <string>
#include <list>
#include <fstream>

// Declare a structure called Employee with appropriate member variables
struct Employee
{
    std::string fname;
    std::string lname;
    long id;
    double salary;
};

// read the file contents into member variables of the Employee structure.
// Create a STL list of the structure.
std::list<Employee> get_employees( std::string file_name )
{
    std::list<Employee> result ;

    std::ifstream file(file_name) ;
    Employee emp ;
    while( file >> emp.fname >> emp.lname >> emp.id >> emp.salary ) result.push_back(emp) ;

    return result ;
}

// remove an entry by ID
bool erase( std::list<Employee>& lst, long id_2b_removed )
{
    for( auto iter = lst.begin() ; iter != lst.end() ; ++iter )
    {
        if( iter->id == id_2b_removed )
        {
            lst.erase(iter) ;
            return true ;
        }
    }

    return false ; // requested id was not found
}

void print( const Employee& emp )
{
    std::cout << emp.fname << ' ' << emp.lname << ' '
              << emp.id << ' ' << emp.salary << '\n' ;
}

bool starts_with( const std::string& str, char ch )
{ return !str.empty() && str.front() == ch ; }

// list the data of the employees with the last name starting with a character
void print_selected( const std::list<Employee>& lst, char lname_start )
{
    for( auto iter = lst.begin() ; iter != lst.end() ; ++iter )
        if( starts_with( iter->lname, lname_start ) ) print(*iter) ;
}

int main()
{
    std::list<Employee> info = get_employees( "test.txt" ) ;

    // ...
}
Thanks Peter87 and JLBorges with your responses. So I couldn't understand how to make two functions do the different actions in them and return it back to main, so that is why I had it in all one function. What I am getting from your code JLBorges is that you suggest making multiple functions being that one creates the STL For the Structure Employee,one to remove entry by ID,one to print the list, one to compare the string and first character in the string, and then list the data of the employees only with the last name starting with a character, and then call all of those functions to the Main?
The only functions that you are required to write are one to remove entry by ID, and another to list the data of the employees with the last name starting with a particular character.

With the code that I posted, your complete main() would look something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main()
{
    // get the list of employees from data in the file
    std::list<Employee> info = get_employees( "test.txt" ) ;

    // ask the user for the id of the employee to be removed from the list
    std::cout << "id to remove? " ;
    long id_2b_removed ;
    std::cin >> id_2b_removed ;

    // try to removed employee with that id
    std::cout << "employee with id " << id_2b_removed << " was " ;
    if( erase( info, id_2b_removed ) )  std::cout << "removed\n" ;
    else std::cout << "not found\n" ;

    // ask the user for the first character of the last name
    std::cout << "first character of the last name? " ;
    char first_char ;
    std::cin >> first_char ;

    // list the employees with the last name starting with first_char
    print_selected( info, first_char ) ;
}
Ok thanks for the tip. So for what I wanted to do was let the user see the list first then Decide whether which ID to get rid of and that part works. It is the second function that is giving me problems.
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
void erased_entry(list<Employee>& newinfo, long int IDERASED, Employee F)
{
        list<Employee>::iterator iter=newinfo.begin();

        for(iter=newinfo.begin();iter!=newinfo.end();++iter)
        {


                if(iter->ID ==  IDERASED)
                      iter=newinfo.erase(iter);
                F=*iter;
                cout << F.fname << " " << F.lname << " " << F.ID << " " << F.salary << endl;
        }

}

void new_list(list<Employee>& newinfo, char firstchar, Employee G)
{

        list<Employee>::iterator iter=newinfo.begin();

        for(iter=newinfo.begin(); iter!=newinfo.end(); ++iter);
        {
                if(!iter->lname.at(0) == firstchar)
                        {
                                iter=newinfo.erase(iter);
                        }
                G=*iter;
                cout << G.fname << " " << G.lname << " " << G.ID << " " << G.salary << endl;
        }

}


Inside the test.txt file is this:

John Harris 1000 35000.00
Lisa Smith 1002 75000.00
Adam Johnson 1007 68500.00
Sheila Smith 1009 10000.00
Tristen Major 1012 75800.00
Yannic Lennart 1015 58000.00
Lorena Emil 1018 43000.00
Tereza Santeri 1020 48000.00


So when I prompt the user to give me a character to only list it gives me the last entry in the list container Tereza Santeri 1020 48000.00

Do you know what I might be doing wrong for it to only print out that one iterator?
Here is my new code:
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
#include <iostream>
#include <list>
#include <fstream>
#include <string>
using namespace std;

struct Employee
{
        string fname;
        string lname;
        long int ID;
        double salary;
};

// Function Declarations
void erased_entry(list<Employee>& newinfo, long int IDERASED, Employee F);
void new_list(list<Employee>& newinfo, char firstchar,Employee F);


int main()
{
        // Declared variables
        list<Employee> info;
        Employee E;
        string fname,lname;
        long int ID, ID2;
        char first_char;
        double salary;
        ifstream in_file;
        // Open text file
        in_file.open("test.txt");

        while(in_file>>fname>>lname>>ID>>salary)
        {
                E.fname=fname;
                E.lname=lname;
                E.ID=ID;
                E.salary=salary;
                info.push_back(E);
        }
        // Initializing iterator and seeding it to the front
        list<Employee>::iterator iter=info.begin();
        // Print out list
        for(iter=info.begin();iter!=info.end();iter++)
        {
                E=*iter;
                cout<<E.fname<<" "<<E.lname<<" "<<E.ID<<" "<<E.salary<<endl;
        }
        // Prompt User for Removing entry by ID
        cout << "Please indicate an ID to be removed:";
        cin >> ID2;
        ID = ID2;
        cout << endl;
        //Call function here
        erased_entry(info,ID,E);
        //Prompt User here
        cout << "Please indicate what employees you would like to see with a char$
        cin >>  first_char;
        cout << endl;
        //Call function here
        new_list(info,first_char,E);
        //Close test.txt
        in_file.close();
        return 0;
}
void erased_entry(list<Employee>& newinfo, long int IDERASED, Employee F)
{
        list<Employee>::iterator iter=newinfo.begin();

        for(iter=newinfo.begin();iter!=newinfo.end();++iter)
        {


                if(iter->ID ==  IDERASED)
                      iter=newinfo.erase(iter);
                F=*iter;
                cout << F.fname << " " << F.lname << " " << F.ID << " " << F.salary << endl;
        }

}
void new_list(list<Employee>& newinfo, char firstchar, Employee G)
{

        list<Employee>::iterator iter=newinfo.begin();

        for(iter=newinfo.begin(); iter!=newinfo.end(); ++iter);
        {
                 if(!iter->lname.at(0) == firstchar)
                        {
                                iter=newinfo.erase(iter);
                        }
                G=*iter;
                cout << G.fname << " " << G.lname << " " << G.ID << " " << G.salary << endl;
        }
}

 

if(!iter->lname.at(0) == firstchar) this is wrong syntax and notion if you're checking for equality
Also see here:
http://stackoverflow.com/questions/596162/can-you-remove-elements-from-a-stdlist-while-iterating-through-it
It seems that a while loop is preferred over a for loop
Alternatively:
1
2
3
4
5
6
7
8
9
void new_list(list<Employee>& newinfo, char firstchar, Employee G)
{

     newinfo.remove_if([firstchar](const Employee& G){return G.lname.at(0) == firstchar;});
     for(auto& elem : newinfo)
     {
         cout << elem.fname << " " << elem.lname << " " << elem.ID << " " << elem.salary << endl;
     }
}

Topic archived. No new replies allowed.