Search code examples
c++ifstream

ofstream File is being overwritten every iteration


My program tries to create a new "record" at an index specified by the user. Once the user creates this new record, all of the old records are overwritten and I'm not sure why.

In the code, I'm trying to create two new records, and the first record is no longer in the file but the second one is.

If I only do one record, the program works perfectly, but it's only when I try to add two or more records to the credits.dat that it then overwrites everything

#include <fstream>
#include <iostream>

using namespace std;
struct clientData {
    int accountNumber;
    char lastName[15];
    char firstName[10];
    float balance;
};

void initializeFile();
void getClientInfo();
void printAllInfo();
void printUserByIndex(int);

int main() {
    initializeFile();
    getClientInfo();
    getClientInfo();

    cout << "Which index would you like to get the data at?" << endl;
    int userIndex;
    cin >> userIndex;
    printUserByIndex(userIndex);
    printAllInfo();
    return 0;
}

void printAllInfo() {
    ifstream inCredit("credit.dat", ios::in);
    clientData lastClient;
    for (int i = 1; i < 100; i++) {
        clientData newClient;
        inCredit.seekg((i - 1) * sizeof(clientData));
        inCredit.read(reinterpret_cast<char*>(&newClient), sizeof(clientData));
        cout << "Account number: " << newClient.accountNumber << endl;
        cout << "First name: " << newClient.firstName << endl;
        if (newClient.accountNumber != 0
                && lastClient.accountNumber != newClient.accountNumber) {
            cout << "Account number: " << newClient.accountNumber << endl;
            cout << "First name: " << newClient.firstName << endl;
            cout << "Last name: " << newClient.lastName << endl;
            cout << "Account balance: " << newClient.balance << endl;
            lastClient = newClient;
        }
    }
}

void printUserByIndex(int index) {
    ifstream inCredit("credit.dat", ios::in);
    clientData newClient;
    inCredit.seekg((index - 1) * sizeof(clientData));
    inCredit.read(reinterpret_cast<char*>(&newClient), sizeof(clientData));
    cout << "Account number: " << newClient.accountNumber << endl;
    cout << "First name: " << newClient.firstName << endl;
    cout << "Last name: " << newClient.lastName << endl;
    cout << "Account balance: " << newClient.balance << endl;
    cout << endl;
}

void getClientInfo() {
    clientData client1;
    ofstream outCredit1("credit.dat", ios::ate);
    cout << "Please enter a number between 1 and 100!" << endl;
    cin >> client1.accountNumber;
    cout << "Please enter the client's first name" << endl;
    cin >> client1.firstName;
    cout << "Please enter the client's last name" << endl;
    cin >> client1.lastName;
    cout << "Please enter the client's balance name" << endl;
    cin >> client1.balance;
    outCredit1.seekp((client1.accountNumber - 1) * sizeof(clientData));
    outCredit1.write(reinterpret_cast<const char*>(&client1),
            sizeof(clientData));
    outCredit1.close();
}

void initializeFile() {
    ofstream outCredit("credit.dat", ios::out);
    clientData blankClient = { 0, "", "", 0.0 };
    for (int i = 0; i < 100; i++) {
        outCredit.write(reinterpret_cast<char *>(&blankClient.accountNumber),
                sizeof(int));
        outCredit.write(blankClient.lastName, sizeof(char) * 30);
        outCredit.write(reinterpret_cast<char *>(&blankClient.firstName),
                sizeof(char) * 10);
        outCredit.write(reinterpret_cast<char *>(&blankClient.balance),
                sizeof(float));
    }
    outCredit.close();
}

Solution

  • We need to tell the computer the purpose of opening our file. For e.g.- to write on the file, to read from the file, etc. These are the different modes in which we can open a file.

    (ios::app)-opens a text file for appending. (appending means to add text at the end).

    (ios::ate)-opens a file for output and move the read/write control to the end of the file.

    (ios::in)-opens a text file for reading.

    (ios::out)-opens a text file for writing.

    (ios::trunc)-truncates the content before opening a file, if file exists.

    void initializeFile() {
      ofstream outCredit("credit.dat", ios::app);
      clientData blankClient = { 0, "", "", 0.0 };
      for (int i = 0; i < 100; i++) {
         outCredit.write(reinterpret_cast<char *>(&blankClient.accountNumber),
                 sizeof(int));
         outCredit.write(blankClient.lastName, sizeof(char) * 30);
         outCredit.write(reinterpret_cast<char *>(&blankClient.firstName),
                 sizeof(char) * 10);
         outCredit.write(reinterpret_cast<char *>(&blankClient.balance),
                sizeof(float));
       }
      outCredit.close();
     }
    

    ios::app will write your code after your first code. ofstream outCredit("credit.dat", ios::app)

    And if you want to replace a specific element from the file then you will load in program and after modification write to the file.

    If you want to ask more about file-Handling than comment it.