【问题标题】:Ofstream file overwritten whenever it's openedOfstream 文件在打开时被覆盖
【发布时间】:2017-04-10 10:07:12
【问题描述】:

所以我必须为一项作业制作一个银行程序,而我的教授想要每个“操作”的日志文件(他对此真的很模糊,我决定记录输入和输出)。我遇到的问题是,每次我调用一个新函数时,我都必须重新打开文件,它会覆盖以前存在的内容。据我所知,重复使用 .open 会导致我所在的任何函数忽略之前的输出。
我尝试声明一个全局 ofstream 希望它会改变,但问题仍然存在。冲洗和/或关闭似乎没有帮助,但我完全有可能滥用它们或语法错误。下面的代码是main函数、read_accts函数、menu函数。如果我在调用 read_accts 函数之前终止程序,日志文件将显示“有多少帐户?”但是如果我允许程序调用其他两个函数,那么日志文件只有菜单文件的输出。我为这篇长篇文章道歉,但我不知道出了什么问题。

int main()
{
    ofstream log;
    log.open("Log.txt");
    int MAX_NUM = 100;
    BankAccount account[MAX_NUM];
    int num_accts = 0;
    char selection = 'Z';
    cout << "How many accounts are there?" << endl;
    log << "How many accounts are there?" << endl;
    cin >> MAX_NUM;
    read_accts(account, MAX_NUM, num_accts);
    cout << endl;
    cout << "There are " << num_accts << " accounts" << endl;
    log << "There are " << num_accts << " accounts" << endl;
    cout << endl;
    print_accts(account, MAX_NUM);
    cout << endl;
    `

    while (selection != 'Q' && selection != 'q')
    {

        menu();
        cin >> selection;
        log << selection;
        switch (selection)
        {
            case 'W':
                case 'w':
                withdrawal(account, num_accts);
                break;
            case 'D':
                case 'd':
                deposit(account, num_accts);
                break;
            case 'N':
                case 'n':
                new_acct(account, num_accts);
                break;
            case 'B':
                case 'b':
                balance(account, num_accts);
                break;
            case 'I':
                case 'i':
                account_info(account, num_accts);
                break;
            case 'C':
                case 'c':
                close_acct(account, num_accts);
                break;
            case 'Q':
                case 'q':
                print_accts(account, num_accts);
                break;
            default:
                cout << "Invalid selection" << endl;
                log << "Invalid selection" << endl;

        }
        cout << endl;
    }
    print_accts(account, MAX_NUM);
    cout << "Goodbye" << endl;
    log.close();
    return 0;
}

int read_accts(BankAccount account[], int MAX_NUM, int &num_accts)
{
    ofstream log;
    log.open("log.txt", std::ofstream::app);
    string f;
    string l;
    int social;
    int acct;
    string type;
    double bal;
    int i = 0;
    ifstream readfile;
    readfile.open("bankdatain.txt");
    if (!readfile)
    {
        cout << "Can't open input file." << endl;
        log << "Can't open input file." << endl;
        exit(1);
    }
    while (readfile >> f >> l >> social >> acct >> type >> bal)
    {
        account[i].setfname(f);
        account[i].setlname(l);
        account[i].setssnum(social);
        account[i].setacctnum(acct);
        account[i].settype(type);
        account[i].setbalance(bal);
        i++;
        num_accts++;
    }

    return num_accts;
}

void menu()
{
    ofstream log;
    log.open("Log.txt");
    cout << "W - Withdrawal" << endl;
    log << "W - Withdrawal" << endl;
    cout << "D - Deposit" << endl;
    log << "D - Deposit" << endl;
    cout << "N - New account" << endl;
    log << "N - New account" << endl;
    cout << "B - Balance" << endl;
    log << "B - Balance" << endl;
    cout << "I - Account Info" << endl;
    log << "I - Account Info" << endl;
    cout << "C - Close Account" << endl;
    log << "C - Close Account" << endl;
    cout << "Q - Quit" << endl;
    log << "Q - Quit" << endl;
    cout << "Please make your selection: " << endl;
    log << "Please make your  selection: " << endl;
}

【问题讨论】:

标签: c++ overwrite ofstream


【解决方案1】:

据我所知,默认情况下,ofstream 将以 std::fstream::out 模式打开文件,如果将删除现有文件或创建新文件。

将其更改为 std::fstream::app http://www.cplusplus.com/reference/fstream/fstream/open/

编辑: 好像您只对一个文件使用了两个 ostream。不能拒绝访问Using std:fstream how to deny access (read and write) to the file

将ostream传递给被调用函数

int read_accts(BankAccount account[],int MAX_NUM,int &num_accts, ostream& log)
{
log.open("log.txt",std::ofstream::app); // remove this line since you already open it in main()

在 main 中调用它

read_accts(account,MAX_NUM,num_accts, log);

【讨论】:

  • Fstream 没有区别,是否有可能在 main() 中使用“file.open”然后在另一个函数中再次使用它会导致问题?如果可能的话,我想我正在寻找一种方法来让文件在每个函数中都保持打开状态。
  • @CharlieMonnone 更新了!
  • 将日志作为参数传递似乎不起作用;据我所知,一旦我调用 read_accts 函数 ofstream 停止工作。
  • @CharlieMonnone 你应该删除 read_accts 中的 .open ,因为你已经在 main 中打开了文件,然后你传递它的引用,它不需要再次打开它。
  • 它现在正在工作,正在删除 log.open("log.txt",std::ofstream::app);成功了。谢谢!。
【解决方案2】:

我认为你唯一的问题是你必须在写入文件之前添加这个。

log.seekp(0, std::ios_base::end);

这会将文件指针设置到文件末尾并继续从那里写入。

您的文件已经在int main () 中打开,如果您将变量log 传递给函数int read_accts(BankAccount account[], int MAX_NUM, int &amp;num_accts) 会更好 并使其成为int read_accts(BankAccount account[], int MAX_NUM, int &amp;num_accts, ofstream log );

并做出定义

int read_accts(BankAccount account[], int MAX_NUM, int &num_accts, ofstream log )
{
    string f;
    string l;
    int social;
    int acct;
    string type;
    double bal;
    int i = 0;
    ifstream readfile;
    readfile.open("bankdatain.txt");
    if (!readfile)
    {
        cout << "Can't open input file." << endl;
        log << "Can't open input file." << endl;
        exit(1);
    }
    while (readfile >> f >> l >> social >> acct >> type >> bal)
    {
        account[i].setfname(f);
        account[i].setlname(l);
        account[i].setssnum(social);
        account[i].setacctnum(acct);
        account[i].settype(type);
        account[i].setbalance(bal);
        i++;
        num_accts++;
    }

    return num_accts;
} 

PS seekp() 的语法是

  ostream& seekp (streampos pos);
  ostream& seekp (streamoff off, ios_base::seekdir way);

参考here

PSifstream 的等效项是 seekg ( 0, std::ios_base::end )

【讨论】:

    猜你喜欢
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多