-1

I'm trying to read a text file into an array of structure. I haven't figured out a way to input it into an array of structure yet but the problem with my code is that the output keeps looping. I'm new to C++ as this is the first programming course I am taking.

This is the text file of records I've put in separated by "tab".

1   Clark Kent  012-1449326 221, Jalan Pudu, Kuala Lumpur   clark_kent@gmail.com
2   Bruce Wayne 013-9817470 65, Jalan Jejaka, Kuala Lumpur  bruce_wayne@hotmail.com
3   Peter Parker 017-6912495    26, Jalan Rajabot, Kuala Lumpur peterparker@zoho.net
4   Yeoman Prince   014-1374040 22, Jalan 1/109e, Kuala Lumpur  yeoman_prince@yahoo.com
5   Tony Stark  016-7473151 21, Jalan Pandan, Kuala Lumpur  tonystark@zoho.net
6   Selina Kyle 012-4040928 Wisma Cosway, Kuala Lumpur  selina_kyle@gmail.com
7   Steve Rogers    018-9285217 Desa Pandan, Kuala Lumpur   steverogers@hotmail.com
8   Alan Scott  019-5569400 2, Jalan U1/17, Shah Alam   alanscott@gmail.com
9   Britt Reid  011-7876738 43, Jalan SS2/23, Petaling Jaya brittreid@yahoo.com
10  Darcy Walker    011-4042788 Blok B, Setapak, Kuala Lumpur   darcywalker@gmail.com
11  Reed Richards   019-2299339 Menara U, Bangsar, Kuala Lumpur reedrichards@zoho.net
12  Barbara Gordon  017-2297980 The Boulevard, Kuala Lumpur barbaragordon@gmail.com
13  Don Diego Vega  012-4142987 10, Jalan Wangsa, Kuala Lumpur  donvega@zoho.net
14  Billy Batson    013-9200151 122, Jalan Jejaka, Kuala Lumpur billybatson@hotmail.com
15  Barry Allen 017-7928822 Wisma Laxton, Kuala Lumpur  barryallen@gmail.com
16  Stanley Beamish 014-9177437 203, Sunwaymas, Batu Caves  stanleybeamish@yahoo.com
17  Dick Grayson    017-4023800 Pekeliling Bus, Kuala Lumpur    dickgrayson@hotmail.com
18  James Howlett   012-7816910 Sri Hartamas, Kuala Lumpur  jameshowlett@zoho.net
19  Hal Jordan  013-3439897 302, Jalan Ampang, Kuala Lumpur haljordan@yahoo.com
20  Scott Summers   012-9057100 Menara Summit, Subang Jaya  scottsummers@zoho.net

This is my struct:

struct Employee {
int staffId;
char fullName[30];
char phoneNum[15];
char address[40];
char email[30];
};

The function call of read:

int main(void) {
int choice;
int value = 0;
Employee data;
menu();

cin >> choice;
do {
    if (choice == 1) {
        read();
    }
    else if (choice == 2) {
        add(value, &data);
    }
    else if (choice == 3) {
        list(value, &data);
    }
    else if (choice == 4) {
        search();
    }
    else if (choice == 5) {
        update();
    }
    else if (choice == 6) {
        deletes();
    }
    else if (choice == 7) {
        exit();
    }
    else {
        cout << "\n **Invalid choice option. Please enter from numbers 1 to 7 : ";
        cin >> choice;
    }

} while (choice != 1 || choice != 2 || choice != 3 || choice != 4 || choice != 5 || choice != 6 || choice != 7);

return 0;

}

This is my code to read the file:

void process(string* line) {
    cout << "line read: " << *line << endl;
}

void read()
{
    string line;
    ifstream in("list.txt");

    if (!in.is_open()) {
        cerr << "File can't be opened! " << endl;
    }
    while(getline(in,line)) {
        process(&line);
    }

    if (in.bad()) {
        cerr << "File can't be read! " << endl;
    }
    in.close();
    return;
}

This is my output:

line read: 1    Clark Kent      012-1449326     221, Jalan Pudu, Kuala Lumpur   clark_kent@gmail.com
line read: 2    Bruce Wayne     013-9817470     65, Jalan Jejaka, Kuala Lumpur  bruce_wayne@hotmail.com
line read: 3    Peter Parker    017-6912495     26, Jalan Rajabot, Kuala Lumpur peterparker@zoho.net
line read: 4    Yeoman Prince   014-1374040     22, Jalan 1/109e, Kuala Lumpur  yeoman_prince@yahoo.com
line read: 5    Tony Stark      016-7473151     21, Jalan Pandan, Kuala Lumpur  tonystark@zoho.net
line read: 6    Selina Kyle     012-4040928     Wisma Cosway, Kuala Lumpur      selina_kyle@gmail.com
line read: 7    Steve Rogers    018-9285217     Desa Pandan, Kuala Lumpur       steverogers@hotmail.com
line read: 8    Alan Scott      019-5569400     2, Jalan U1/17, Shah Alam       alanscott@gmail.com
line read: 9    Britt Reid      011-7876738     43, Jalan SS2/23, Petaling Jaya brittreid@yahoo.com
line read: 10   Darcy Walker    011-4042788     Blok B, Setapak, Kuala Lumpur   darcywalker@gmail.com
line read: 11   Reed Richards   019-2299339     Menara U, Bangsar, Kuala Lumpur reedrichards@zoho.net
line read: 12   Barbara Gordon  017-2297980     The Boulevard, Kuala Lumpur     barbaragordon@gmail.com
line read: 13   Don Diego Vega  012-4142987     10, Jalan Wangsa, Kuala Lumpur  donvega@zoho.net
line read: 14   Billy Batson    013-9200151     122, Jalan Jejaka, Kuala Lumpur billybatson@hotmail.com
line read: 15   Barry Allen     017-7928822     Wisma Laxton, Kuala Lumpur      barryallen@gmail.com
line read: 16   Stanley Beamish 014-9177437     203, Sunwaymas, Batu Caves      stanleybeamish@yahoo.com
line read: 17   Dick Grayson    017-4023800     Pekeliling Bus, Kuala Lumpur    dickgrayson@hotmail.com
line read: 18   James Howlett   012-7816910     Sri Hartamas, Kuala Lumpur      jameshowlett@zoho.net
line read: 19   Hal Jordan      013-3439897     302, Jalan Ampang, Kuala Lumpur haljordan@yahoo.com
line read: 20   Scott Summers   012-9057100     Menara Summit, Subang Jaya      scottsummers@zoho.net
line read: 1    Clark Kent      012-1449326     221, Jalan Pudu, Kuala Lumpur   clark_kent@gmail.com
line read: 2    Bruce Wayne     013-9817470     65, Jalan Jejaka, Kuala Lumpur  bruce_wayne@hotmail.com
line read: 3    Peter Parker    017-6912495     26, Jalan Rajabot, Kuala Lumpur peterparker@zoho.net
line read: 4    Yeoman Prince   014-1374040     22, Jalan 1/109e, Kuala Lumpur  yeoman_prince@yahoo.com
line read: 5    Tony Stark      016-7473151     21, Jalan Pandan, Kuala Lumpur  tonystark@zoho.net

Any ways to suggest it stop looping? I'm trying to refrain from putting a set size like 20 because in another part of the program, I'm supposed to add more employee records. So, my question is:

  1. How do you stop it from infinitely looping?
  2. How to input the lines read into an array of structure?

Thank you in advance.

  • 1
    The code you have posted will not loop for ever. It must be happening because you are calling `read` over and over. Unfortunately you didn't show us that part of the code. – john Jul 31 '18 at 12:36
  • 1
    In addition to the above: `void main` is non-standard C++. – Algirdas Preidžius Jul 31 '18 at 12:38
  • 3
    @KateKarat "I'm trying to refrain from putting a set size like 20 because in another part of the program, I'm supposed to add more employee records." sounds like you should use a `std::vector` instead of an array and `std::string` instead of arrays of `char`. – Swordfish Jul 31 '18 at 12:40
  • 1
    Can you post the implementation of the function that calls `void read()` ? – PhoenixBlue Jul 31 '18 at 12:57
  • You are completely ignoring your `Employee` struct in `main`, and just echoing the line you have read – Caleth Jul 31 '18 at 13:58
  • @PhoenixBlue i have just edited it and posted it! – Kate Karat Jul 31 '18 at 14:07
  • @john i have just shown the code in my latest edit – Kate Karat Jul 31 '18 at 14:09
  • @Swordfish i can't use vector or arrays of char as my assignment has stated i only use array of structure – Kate Karat Jul 31 '18 at 14:10
  • 1
    Still not complete... what is the condition out of the `do {}while();` loop? do you break after the call to `read()` ? – PhoenixBlue Jul 31 '18 at 14:11
  • Consider moving `cin >> choice;` inside the `do {} while` loop. – Bob__ Jul 31 '18 at 14:13
  • @PhoenixBlue it is complete now – Kate Karat Jul 31 '18 at 15:01
  • The solution, as mentioned by @Bob_, move the statement `cin>>choice` into the loop. Within the loop, the choice is and will always be 1! You need a modifier to that value. Also, I do not agree with your while condition... Kind of messy. Rather put something simpler like `while(choice!=7);` or `while(choice<7 && choice >0);` – PhoenixBlue Jul 31 '18 at 15:24

3 Answers3

1

Try this, read from file line by line, and then parse each line according to the delimiter \t.

void readFile(const string& filename) {
    ifstream ifs(filename);

    string line;
    while (getline(ifs, line)) {
        istringstream iss(line);
        string token;

        Employee emp;

        while (getline(iss, token, '\t')) {
            // if you just want to print the information
            cout << token << '\t';
            // or you can store it in an Employee object
            // ...
        }
        cout << endl;
    }
}
hiimdaosui
  • 361
  • 2
  • 12
  • I get red line in Microsoft Visual Studio for this line `istringstream **iss**(line);` and this line `while (**getline**(iss, token, '\t')) {` though. Thanks for your help though!! – Kate Karat Jul 31 '18 at 14:58
  • 1
    @KateKarat as Bob__ mentioned, did you include the library? – hiimdaosui Jul 31 '18 at 15:08
  • thank you Bob__ i have included however i still can't run the code. the program requests that i add more arguments into my read() function call @hiimdaosui – Kate Karat Jul 31 '18 at 15:27
  • @KateKarat In my code, I passed a parameter `filename` in the read function. You can follow my route to do so, or you can just remove it and do what you have previously done, i.e. without passing any additional filename to the function, and initialize `ifstream ifs("yourfilenamehere.withextension")` in this way. – hiimdaosui Jul 31 '18 at 16:12
  • thank you, it worked without error! however, i'm trying to (1) display what i've read out then (2) input it into a structure of array. how do I display the contents of the file I've read? – Kate Karat Aug 01 '18 at 10:59
1

The problem is that you never ask the user for a new menu choice, so your program gets stuck in the first choice and loops indefintely.

Your loop should look like this with cin >> choice; inside the do loop.

do {
    cin >> choice;
    if (choice == 1) {
        read();
    }
    ...

With this change you'll also need to rewrite your error handling logic as well, but I'll leave that to you.

And as Bob__ says in the comments below the logic of your loop condition is wrong choice != 1 || choice != 2 || choice != 3 || choice != 4 || choice != 5 || choice != 6 || choice != 7 is always true, so your loop will never terminate.

In any case there are several errors in your overall program logic, and those are what you should fix before getting into the functionallity of individual menu items.

john
  • 85,011
  • 4
  • 57
  • 81
0

The second part of your question is a little vague. Are you trying to input the data to your struct, or are you trying to create an array of type employee and place each employee's data into an index of that array? In either case I'll answer the latter.

As for your first question, stopping the infinite loop is simple. while (choice != 1 || choice != 2 || choice != 3 || choice != 4 || choice != 5 || choice != 6 || choice != 7) is your problem. The logic in this line is: "If the user inputs a number not equal to 1 or 2 or 3...continue doing the loop." However, this means no matter what number the user enters, your loop will continue. Assuming your goal is to continue asking the user for choice until they specify otherwise, a better loop would be:

do{
    cin >> choice;
    ...
}
while(choice != 0);

In this case, if a user inputs a number other than 0-7, the program goes to cout << "\n **Invalid choice option. Please enter from numbers 1 to 7 : " but if the user enters 0, the program ends. You can change 0 to whatever you like.

As for entering data into a struct, the process is quite simple. Generally you would use an overloaded >> operator, but that seems beyond your current scope right now so we'll do it a more basic way. Unless you know for certain the number of employees you'd like to read in, you'll need to use a vector of type employee. Change your array of char to strings in your struct for ease of use. The following code is a template for how to read in the data.

vector<employee> parse_text(){
    ifstream fin("lines.txt");
    vector<employee> employees;
    while(!fin.eof()){
        string temp_id, temp_fname, temp_lname;
        employee temp;
        fin >> temp_fname >> temp_lname;
        temp.fullName = temp_fname + temp_lname;
        fin >> temp_id;
        temp.staffId = (int)temp_id;
        ...
        employees.push_back(temp);
        }
    fin.close();
    return employees;
}

Obviously you will have to add a few lines but that should be more than enough to get you started. It currently reads in the first and last name of an employee, concatenates them, and stores this as your employee's fullName. It then reads in the employee's ID, casts it as an int (because getline stores a string), and then stores this as staffId. Rinse and repeat for the remaining variables and you'll have yourself a vector of employees.

Short Tail
  • 21
  • 1
  • Thank you for suggesting vector but my assignment requires me to use array of structure to read the variables off the text file – Kate Karat Aug 01 '18 at 03:14
  • A vector is an array, just of variable size. You can use a standard array for this, but you must know the amount of employees prior to filling the array or you won't have enough space. You could initialize the array to have hundreds of entries but that isn't good practice and is a waste of memory. – Short Tail Aug 02 '18 at 18:19