0

I am trying to read from a file and output data to a separate file. Only problem is that when I run the program the output on the file is from the data on the last line of the input file. I also don't want to append the output file since I don't want the data to duplicate when I rerun the program which is why i'm not using ios::app in the output.

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

//class declaration
class call_record{
public:
string cell_number;
int relays;
int call_length;
double net_cost;
double tax_rate;
double call_tax;
double total_cost;

};

//Prototypes

void input(ifstream & in, call_record &);
void process(call_record &);
void output(call_record &);

//Input function

void input(ifstream & in, call_record & customer_record){
    in >> customer_record.cell_number >> customer_record.relays >> 
    customer_record.call_length;
}

//Process function
void process(call_record & customer_record){

    if(customer_record.relays >= 0 && customer_record.relays <=5){
        customer_record.tax_rate = 0.01;
    } else if(customer_record.relays >= 6 && customer_record.relays <=11){
        customer_record.tax_rate = 0.03;
    } else if(customer_record.relays >= 12 && customer_record.relays <=20){
        customer_record.tax_rate = 0.05;
    } else if(customer_record.relays >= 21 && customer_record.relays <=50){
        customer_record.tax_rate = 0.12;
    }

    //net cost of call
    customer_record.net_cost = (customer_record.relays/50 * 0.40 * 
customer_record.call_length);

    //cost of tax on call
    customer_record.call_tax = customer_record.net_cost * 
customer_record.tax_rate;

//Total cost of call
customer_record.total_cost = customer_record.net_cost + 
customer_record.call_tax;

}

void output(call_record & customer_record){
ofstream out("weekly_call_info.txt");

out.setf(ios::showpoint);
out.precision(2);
out.setf(ios::fixed);

out << customer_record.cell_number << "   " << customer_record.relays << "   " 
<< customer_record.call_length << "   " << customer_record.net_cost << "   " 
<< customer_record.tax_rate << "   " << customer_record.call_tax << "   " << 
customer_record.total_cost << endl;

out.close();
}

int main(){

call_record customer_record;

ifstream in("call_data.txt");


if(in.fail()){
    cout << "Your input file does not exist or did not open properly." << 
endl;

} else {
    while (!in.eof()){
        input(in, customer_record);
        process(customer_record);
        output(customer_record);
    }
}

in.close();

return 0;
}

This is different than the other posts because I am using both an input stream and an output stream in 2 separate functions and I don't think I fully understand how to implement them correctly in my main function.

Preview
  • 35,317
  • 10
  • 92
  • 112

1 Answers1

0

The problem is that you are always creating weekly_call_info.txt each time output() is called and truncating the existing file. This is because you are not specifying the std::ios_base::app ("append") open mode flag, so the existing content of weekly_call_info.txt is lost. See this page for a helpful table that shows the equivalent C-style mode strings for the different combinations of open mode flags: http://en.cppreference.com/w/cpp/io/basic_filebuf/open

I suggest passing a reference to the std::ostream to which you want to output data to the output() function:

void output(call_record & customer_record, std::ostream& out){
    out << customer_record.cell_number << "   " << customer_record.relays << "   " 
    << customer_record.call_length << "   " << customer_record.net_cost << "   " 
    << customer_record.tax_rate << "   " << customer_record.call_tax << "   " << 
    customer_record.total_cost << endl;
}

int main(){
    call_record customer_record;

    ifstream in("call_data.txt");


    if(in.fail()){
        cout << "Your input file does not exist or did not open properly." << endl;
    } else {
        ofstream out("weekly_call_info.txt");
        out.setf(ios::showpoint);
        out.precision(2);
        out.setf(ios::fixed);

        for (;;) {
            input(in, customer_record);
            if (!in) break;
            process(customer_record);
            output(customer_record, out);
        }
    }

    return 0;
}

If you really do want to open weekly_call_info.txt for writing multiple times, you will want to use the std::ios_base::app open mode flag to append to the existing file. See appending to a file with ofstream.

Community
  • 1
  • 1
Daniel Trebbien
  • 38,421
  • 18
  • 121
  • 193