-2

So I am trying to read a .txt file in c++ program. Each line in the text file has firstName, lastName and yearlySalary (e,g, Tomm Dally, 120000). I can seem to read a file properly - it skips the first column (firstName) and stops reading the data in after first line. Why is that?

#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;

int main()
{

    string fName;
    string lName;
    double yearlyPay;
    double backPayDue;
    double newAnualSalary;
    double newMonthlyWage;
    int numOfEmployees = 0;
    double totalBackPayDue = 0;

    ifstream empSalariesOld("EmpSalaries.txt");
    ofstream empSalariesNew("EmpSalariesNew.txt");
    if (!empSalariesOld.fail())
    {
        while (empSalariesOld >> fName)
        {
            empSalariesOld >> fName >> lName >> yearlyPay;
            std::cout << fName << " " << lName << " " << yearlyPay << endl;
            numOfEmployees++;
        }

    }

    empSalariesOld.close();
    empSalariesNew.close();


    system("pause");
    return 0;
}

1 Answers1

1

You are not reading the lines correctly.

When your while statement calls empSalariesOld >> fName for the first time, it reads an employee's first name. Then, inside the loop body, when you call empSalariesOld >> fName >> lName >> yearlyPay, >> fName reads the employee's last name (because you already read the first name), then >> lName reads the employee's salary, and >> yearlyPay tries to read the next employee's first name and fails!

Try something more like the following instead. Use std::getline() to read a whole line, and then use std::istringstream to parse it:

#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    string fName;
    string lName;
    double yearlyPay;
    //...
    int numOfEmployees = 0;

    ifstream empSalariesOld("EmpSalaries.txt");
    ofstream empSalariesNew("EmpSalariesNew.txt");

    if (empSalariesOld)
    {
        string line;
        while (getline(empSalariesOld, line))
        {
            istringstream iss(line);
            if (iss >> fName >> lName >> yearlyPay) {
                std::cout << fName << " " << lName << " " << yearlyPay << endl;
                ++numOfEmployees;
            }
        }
    }

    empSalariesOld.close();
    empSalariesNew.close();

    cout << "Press any key";
    cin.get();

    return 0;
}

However, if the lines actually have a comma between the name and salary like you showed (Tomm Dally, 120000), then try the following instead:

#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <sstream>

using namespace std;

int main()
{
    string name;
    double yearlyPay;
    //...
    int numOfEmployees = 0;

    ifstream empSalariesOld("EmpSalaries.txt");
    ofstream empSalariesNew("EmpSalariesNew.txt");

    if (empSalariesOld)
    {
        string line;
        while (getline(empSalariesOld, line))
        {
            istringstream iss(line);
            if (getline(iss, name, ',') && (iss >> yearlyPay))
                std::cout << name << " " << yearlyPay << endl;
                ++numOfEmployees;
            }
        }
    }

    empSalariesOld.close();
    empSalariesNew.close();

    cout << "Press any key";
    cin.get();

    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770