-1

I'm relatively new to C++, and have been working my way through taking a data file and reading it, then taking that data doing some math with some of it, and then exporting it all to an output file. However my problem is everytime it runs it skips writing the very first line to the output file.

My data file is:

Jon Doe 15 7.25
Nick Delgado 8 7.25
Jo Barnes 4 7.25
Harold Griffith 45 11.00
Linda Holmes 30 10.00

My output looks like this:

Nick Delgado 8 7.25 58 0 58
Jo Barnes 4 7.25 29 0 29
Harold Griffith 45 11 522.5 146.3 376.2
Linda Holmes 30 10 300 84 216

It's completely skipping writing out any information concerning Jon Doe. Which is:

Jon Doe 15 7.25 108.75 0 108.75

I've tried multiple different ideas, asked my friends, and overall I'm extremely frustrated.

I figure the problem code is in here somewhere:

    if (!dataOutFile.is_open()) {
        cout << "Couldn't open file";
    }
    else {
        dataOutFile << firstName << " " << lastName << " " << hoursWorked << " " << payRate << " " << grossPay << " " << withHolding << " " << takeHomePay << endl;
        cout << "What was wrote to file: \n" << firstName << " " << lastName << " " << hoursWorked << " " << payRate << " " << grossPay << " " << withHolding << " " << takeHomePay << endl;
    }

Because my output window looks like this:

enter image description here

So what that tells me is that it is getting to the code where it writes to the file because it's writing the other four entries past the first one. But also according to the output window it is writing to the file the information that it should- but for some reason it isn't. I'm using the append command so it shouldn't be overwriting anything, and according to the output file it isn't but maybe the first line.

No errors, or warnings, and my debug logs are free of errors. Please help me, any help is appreciated. I also realize the code is kinda messy, and I need to break it down into more functions but I'm just trying to get this to work, and then I can clean it up.

The full code for my program that handles all of this is below, in case anyone needed to see it.

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

// Global Variables
string fileName;
double totalGrossPay = 0;
double totalWithHolding = 0;
double totalTakeHomePay = 0;
double withHoldingLimit = 200;
double withHoldingRate = .28;
double overtimeRate = 1.5;

// Initialize Functions
void readFile();

int main() {
    cout << "What is the name of your file?" << endl;
    getline(cin, fileName);
    readFile();
}

void readFile() {
    // Variables
    string firstName;
    string lastName;
    double hoursWorked;
    double payRate;
    double grossPay;
    double withHolding;
    double takeHomePay;
    double overtime;
    string dataOutFileName = "Salary.out";

    // Intialize and Open Input File
    ifstream file;
    file.open(fileName);
    // Initialize Output File
    ofstream dataOutFile(dataOutFileName);

    // Check to see if file failed to open
    if (!file.is_open()) return;

    // Define variables needed in the while loop.
    string word;
    int i = 1;

    // Actually reads through the file and prints out what the file has.
    while (i != 0) {
        // Pull up the next word in the word file
        file >> word;
        // Firstname
        if (((i - 1) % 4) == 0) {
            firstName = word;
            cout << "First name: " << firstName << "\n";
        }
        // Last name
        else if (((i - 1) % 4) == 1) {
            lastName = word;
            cout << "Last name: " << lastName << "\n";
        }
        // Hours Worked
        else if (((i - 1) % 4) == 2) {
            hoursWorked = atof(word.c_str());
            cout << "Hours Worked: " << hoursWorked << "\n";
        }
        // Pay Rate
        else if (((i - 1) % 4) == 3) {
            payRate = atof(word.c_str());
            cout << "Pay Rate: " << payRate << "\n";
        }
        // Add 1 to i
        i++;
        // If i-1 divides into 4 with no remainder, move to new line
        // Also since we now have all four variables filled in we can do our math
        if (i > 3 && ((i - 1) % 4) == 0) {
            // Gross Pay
            if (hoursWorked > 40) {
                overtime = hoursWorked - 40;
            }
            else {
                overtime = 0;
            }
            if (overtime != 0) {
                grossPay = (40 * payRate) + (overtime * (payRate * overtimeRate));
            }
            else {
                grossPay = hoursWorked * payRate;
            }
            // Withholding
            if (grossPay > withHoldingLimit) {
                withHolding = grossPay * withHoldingRate;
            }
            else {
                withHolding = 0;
            }
            // Take Home pay
            takeHomePay = grossPay - withHolding;
            // Add to totals
            totalGrossPay += grossPay;
            totalWithHolding += withHolding;
            totalTakeHomePay += takeHomePay;
            // Write to file, and print the line so we know it worked!
            dataOutFile.open(dataOutFileName, fstream::app);
            // Check it if is open
            if (!dataOutFile.is_open()) {
                cout << "Couldn't open file";
            }
            else {
                dataOutFile << firstName << " " << lastName << " " << hoursWorked << " " << payRate << " " << grossPay << " " << withHolding << " " << takeHomePay << endl;
                cout << "What was wrote to file: \n" << firstName << " " << lastName << " " << hoursWorked << " " << payRate << " " << grossPay << " " << withHolding << " " << takeHomePay << endl;
            }
            dataOutFile.close();
            // move to new line
            cout << "\n";
        }
        // Check to see if were at the end of the file, if so end while.
        if (file.eof()) {
            i = 0;
        }
    }
    file.close();
}
TheGameiswar
  • 27,855
  • 8
  • 56
  • 94
  • The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Sep 14 '16 at 05:50
  • [Why is file.eof() always wrong](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Blacktempel Sep 14 '16 at 05:52
  • @πάντα ῥεῖ I said I looked through my debug log, and it runs without an error or warning. What more could I possibly do? And I provided every step to reproduce my problem. From the text file I am using for data, to the output it is presenting, and what I am expecting. It's a very clear question, and my code is commented out so I know what every step is doing. I'm not sure what is wrong with my question in your eyes but I presented it the best I possibly could. – user6829333 Sep 14 '16 at 05:54
  • @Blacktempel I don't understand how file.eof() is causing the issue here. Could you elaborate? It's not that the program doesn't end, or prints an extra time. The problem is it skips the first segment. – user6829333 Sep 14 '16 at 05:56
  • Don't run with the debugger. Step. Look at the variables as you step. Note when the reality doesn't match the expected. The debugger can't tell you where the program goes off the rails, but it can help you see. You have to do the looking. – user4581301 Sep 14 '16 at 05:57
  • @user6829333 You probably didn't get what I meant with the _debugger_. That you don't get compiler errors or warnings, doesn't mean the logic of your code is actually correct. – πάντα ῥεῖ Sep 14 '16 at 05:59
  • @user4581301 I've done the looking, I've done the commenting, and I've tried my damndest to include cout statements where I can to help me spot errors. I've looked it over and scanned my code and broke it down multiple times now. – user6829333 Sep 14 '16 at 06:00
  • 2
    The short version of the EOF issue, since it looks like either you didn't read the link or didn't understand it, is you can't tell if you have EOF before you read EOF. And if you read EOF, you didn't get any data to process. 1. Read data. 2. test for error (all errors because much more can go wrong than just EOF) 3. If no error, process data. – user4581301 Sep 14 '16 at 06:01
  • @user6829333 Step through your code line by line, as mentioned. It's not our job to do this for you. – πάντα ῥεῖ Sep 14 '16 at 06:02
  • 1
    When you declare the output stream you already open it. There's no need of reopen and close it at every iteration. – Bob__ Sep 14 '16 at 06:03
  • @user4581301 They're just starting to rant now from lack of understanding our advise. – πάντα ῥεῖ Sep 14 '16 at 06:03
  • @πάντα ῥεῖ The site you linked offered a very interesting read. I've commented my code throughly, and I can explain every single bit of the way what it's doing and why it's doing it. What puzzles me, and I can't for the life of me figure it out is why it's saying it wrote to the file, doesn't print, but then one more run through the while loop later it tells me it wrote to the file, and did write to the file. I'm not sure what else I can do, that's why I came here- and I did ask a very specific question and provided as much information as possible. I don't know why this has to be a riddle. – user6829333 Sep 14 '16 at 06:04
  • @user6829333 And what were your observations when you stepped through your code? There is no _riddle_, it's just you have a simple and common bug in your program. – πάντα ῥεῖ Sep 14 '16 at 06:09
  • 1
    @Bob__ Holy crap, I would have never figured that to be my problem. Thank you so much. As soon as I read your comment, I went and commented out the lines for opening and closing the file, and it worked immediately. I'm assuming it was opening the file twice somehow, and writing the first line to the first iteration of the file but when closing the file it closed them both and when it got reopened and closed from that point forward only one file was open so therefore only one place to write to. Is that accurate? Am I understanding it correctly? – user6829333 Sep 14 '16 at 06:11
  • @πάντα ῥεῖ A common bug because I didn't realize initializing the output file also opened it. So that meant it was opening the same file twice, but probably writing to the first open file. But when I closed it at the end of my loop it closed both files, so when i reopened it again next time i got into the loop it was writing into the file that first write didn't write into. I think I'm understanding why it did it now. I'll be sure to keep your link in mind, and try and understand things further, thank you. – user6829333 Sep 14 '16 at 06:14
  • Not quite. The file's not open twice. The second call to open fails and places the file into an unreadable and unwritable failure state. But the file is still open so `dataOutFile.is_open()` fails to protect you. Always check the error state after a read or write to make sure the operation actually happened. – user4581301 Sep 14 '16 at 06:35
  • Per line validation would likely increase your robustness, [something like this](http://pastebin.com/FvjrRmbD). Good luck. – WhozCraig Sep 14 '16 at 06:58

1 Answers1

2

The i-based state machine is way too complex and totally not needed here. Don't fix it, throw it away.

If you need to read four things, read four things at once. Do it inside the while condition.

 ifstream file(filename);
 ofstream dataOutFile(dataOutFileName);

 while (file >> firstName >> lastName >> hoursWorked >> payRate)
 {
      // you have all four pieces of data
      // calculate and print what you need here
 }

Do not call close() or check for eof() inside the loop.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • I'll be sure to keep this in mind when I go and re-write the code to make it more readable! I didn't even think of doing it that way...Initially I was messing with arrays and got tired of it so I went with this mess. But thanks for showing me an option I hadn't even thought of! – user6829333 Sep 14 '16 at 06:16