You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用指定函数将fstream文件内容输出到控制台?作业代码求助

问题描述

作业要求

从键盘读取firstName、lastName、actBalance并生成记录;若姓氏和名字与文件中现有记录均不同,使用createRecord函数将该记录追加到文件末尾;否则更新时间和账户余额。

我的思路与问题

我计划用createRecord()函数将所有通过cin输入的记录写入clientFile,之后检查重复并写入copyFile,但无法使用给定的不可修改的displayFile()函数显示copyFile的内容,附上代码寻求帮助:

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

void
createRecord (fstream & copyFile, fstream & inClientFile, string & firstName,
          string & lastName, double &actBalance)
{
    string recordFirst, recordLast;
    double recordBalance;
    time_t recordTime;
    time_t currentTime = time(0);

    inClientFile.clear ();
    inClientFile.seekg (0);

    while (inClientFile >> recordFirst >> recordLast >> recordBalance >> recordTime)
    {
        inClientFile.seekp(0, ios::end);
        inClientFile << setw (30) << firstName << ' ' << setw (30) << lastName << ' ' << setw (30) << actBalance << ' ' << setw (30) << currentTime;
    }
}

void
updateRecord (fstream & copyFile,fstream& inClientFile,string& firstName,string& lastName, double &actBalance,
          string firstNameArr[], string lastNameArr[])
{
    string recordFirst, recordLast;
    double recordBalance;
    time_t recordTime;
    time_t currentTime = time (0);
    int counter = 0;
    int j = 0;

    inClientFile.clear ();
    inClientFile.seekg (0);

    while (inClientFile >> recordFirst >> recordLast >> recordBalance >> recordTime)
    {
        if(firstNameArr[j] == recordFirst && lastNameArr[j] == recordLast )
        {
            counter++;
        }
    }
    if(counter = 1)
    {
        copyFile.clear ();
        copyFile.seekp(0, ios::end);
        copyFile << firstNameArr[j] << " " << lastNameArr[j] << " " << recordBalance << " " << currentTime << " " << endl;
        j++;
    }
    else if(counter = 2)
    {
        copyFile.clear ();
        copyFile.seekp(0, ios::end);
        copyFile << firstNameArr[j] << " " << lastNameArr[j] << " " << recordBalance << " " << currentTime << " " << endl;
        j++;
    }
}

void
displayFile (fstream & fptr)
{
    string str1;
    string str2;
    double balance;
    int numAct = 0;
    time_t transTime;
    fptr.clear ();
    fptr.seekg (0);

    while (fptr >> str1 >> str2 >> balance >> transTime)
    {
        cout << setw (15) << str1 << setw (15) << str2 << setw (7) << balance << " " << ctime (&transTime);
        numAct++;
    }
    cout << "Number of records in the file:" << numAct << endl;
}

int
main ()
{
    fstream inClientFile ("clientFile.txt", ios::in | ios::out);
    fstream copyFile ("copyFile.txt", ios::out);

    if (!inClientFile)
    {
        cout << "Creating a new file: ";
        exit (1);
    }

    cout << "Existing file content:";

    string firstName;
    string lastName;
    double actBalance;
    string firstNameArr[100];
    string lastNameArr[100];
    int i = 0;

    cout << "Enter first name, last name, and balance: ";
    while (cin >> firstName >> lastName >> actBalance)
    {
        createRecord (copyFile, inClientFile, firstName, lastName, actBalance);
        firstNameArr[i] = firstName;
        lastNameArr[i] = lastName;
        updateRecord(copyFile, inClientFile, firstName, lastName, actBalance, firstNameArr, lastNameArr);
        i++;
    }

    inClientFile.close();
    copyFile.close();

    displayFile (copyFile);
    return 0;
}
问题分析与修正

核心问题点

  1. 文件流权限与状态错误:调用displayFile时copyFile已关闭,且初始仅以ios::out打开,无读权限,无法读取内容。
  2. createRecord逻辑冗余:循环读取原文件时重复追加同一记录,原文件有多少条记录就写入多少次。
  3. updateRecord逻辑错误:用赋值counter = 1替代判断counter == 1,且j变量未正确遍历数组,重复判断无意义。
  4. 流程设计冗余:无需额外copyFile,直接操作原文件即可完成新增/更新需求。

修正后的代码

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

// 新增记录到文件末尾
void createRecord(fstream& clientFile, const string& firstName, const string& lastName, double actBalance) {
    time_t currentTime = time(0);
    clientFile.seekp(0, ios::end);
    clientFile << setw(15) << firstName << setw(15) << lastName << setw(7) << actBalance << " " << currentTime << endl;
}

// 更新现有记录,返回是否找到并更新
bool updateRecord(fstream& clientFile, const string& firstName, const string& lastName, double actBalance) {
    string recordFirst, recordLast;
    double recordBalance;
    time_t recordTime;
    time_t currentTime = time(0);
    bool found = false;
    streampos prevPos;

    clientFile.clear();
    clientFile.seekg(0);

    // 遍历查找目标记录
    while (clientFile >> recordFirst >> recordLast >> recordBalance >> recordTime) {
        prevPos = clientFile.tellg();
        if (recordFirst == firstName && recordLast == lastName) {
            // 回退到当前记录起始位置,覆盖写入更新内容
            clientFile.seekp(prevPos - (recordFirst.size() + recordLast.size() + to_string(recordBalance).size() + to_string(recordTime).size() + 3));
            clientFile << setw(15) << firstName << setw(15) << lastName << setw(7) << actBalance << " " << currentTime << endl;
            found = true;
            break;
        }
    }
    return found;
}

// 不可修改的displayFile函数
void displayFile(fstream& fptr) {
    string str1;
    string str2;
    double balance;
    int numAct = 0;
    time_t transTime;
    fptr.clear();
    fptr.seekg(0);

    while (fptr >> str1 >> str2 >> balance >> transTime) {
        cout << setw(15) << str1 << setw(15) << str2 << setw(7) << balance << " " << ctime(&transTime);
        numAct++;
    }
    cout << "Number of records in the file:" << numAct << endl;
}

int main() {
    // 以读写+追加模式打开,不存在则创建
    fstream clientFile("clientFile.txt", ios::in | ios::out | ios::app);
    if (!clientFile) {
        // 尝试创建文件
        clientFile.open("clientFile.txt", ios::out);
        clientFile.close();
        clientFile.open("clientFile.txt", ios::in | ios::out | ios::app);
        if (!clientFile) {
            cerr << "无法创建或打开文件" << endl;
            return 1;
        }
    }

    cout << "现有文件内容:" << endl;
    displayFile(clientFile);

    string firstName;
    string lastName;
    double actBalance;

    cout << "\n输入名字、姓氏、余额(输入Ctrl+D结束):";
    while (cin >> firstName >> lastName >> actBalance) {
        // 先尝试更新,未找到则新增
        if (!updateRecord(clientFile, firstName, lastName, actBalance)) {
            createRecord(clientFile, firstName, lastName, actBalance);
        }
        cout << "\n更新后的文件内容:" << endl;
        displayFile(clientFile);
        cout << "\n继续输入(输入Ctrl+D结束):";
    }

    clientFile.close();
    return 0;
}

修正说明

  1. 文件流优化:打开clientFile时添加ios::app确保追加写入,同时支持读写;若文件不存在则自动创建。
  2. createRecord简化:直接定位到文件末尾写入新记录,避免循环重复写入。
  3. updateRecord修复:使用==进行判断,遍历文件查找匹配记录,找到后覆盖更新,返回布尔值标记操作结果。
  4. 流程简化:移除多余的copyFile,直接对原文件进行新增/更新操作,符合作业要求;调用displayFile时文件处于可读状态。

内容的提问来源于stack exchange,提问作者Tùng Vương

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 09:12:06