【问题标题】:C++ ofstream only outputting last line of data from ifstreamC++ ofstream 仅从 ifstream 输出最后一行数据
【发布时间】:2017-05-01 20:09:11
【问题描述】:

我正在尝试从文件中读取数据并将数据输出到单独的文件中。唯一的问题是,当我运行程序时,文件上的输出来自输入文件最后一行的数据。我也不想附加输出文件,因为当我重新运行程序时我不希望数据重复,这就是我不在输出中使用 ios::app 的原因。

#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;
}

这与其他帖子不同,因为我在 2 个单独的函数中同时使用输入流和输出流,我认为我不完全了解如何在我的主函数中正确实现它们。

【问题讨论】:

  • 问题重复表格在哪里,所以我可以找到它
  • 代码中的错误是:while (!in.eof()){ 该链接解释了为什么这是一个错误。
  • 我通读了它,但我仍然无法弄清楚如何修复 while 循环。你能帮我弄清楚吗。我尝试将 while 循环更改为 while(!in.fail()){ 但它仍然不起作用。 @drescherjm
  • 使输入返回布尔值。然后输入:return in &gt;&gt; customer_record.cell_number &gt;&gt; customer_record.relays &gt;&gt; customer_record.call_length;
  • 然后将while (!in.eof()){替换为while(input(in, customer_record)) {

标签: c++ file fstream ifstream ofstream


【解决方案1】:

问题在于,每次调用 output() 并截断现有文件时,您总是在创建 weekly_call_info.txt。这是因为您没有指定std::ios_base::app ("append") 打开模式标志,所以weekly_call_info.txt 的现有内容丢失了。请参阅此页面以获取有用的表格,该表格显示了打开模式标志的不同组合的等效 C 样式模式字符串:http://en.cppreference.com/w/cpp/io/basic_filebuf/open

我建议将一个对 std::ostream 的引用传递给您要将数据输出到的 output() 函数:

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;
}

如果您确实想打开weekly_call_info.txt 进行多次写入,您将需要使用std::ios_base::app 打开模式标志来追加到现有文件。见appending to a file with ofstream

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多