user67265
user67265

Reputation: 269

What is the difference among ios::app, out, and trunc in c++?

I know that the default file open mode is out. And I think out will overwrite the data in the file, but in the following code, it age data doesn’t overwrite name data.

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

int main () {

    char data[100];

    // open a file in write mode.
    ofstream outfile;
    outfile.open("afile.dat");

    cout << "Writing to the file" << endl; 
    cout << "Enter your name: ";
    cin.getline(data, 100);

    // write inputted data into the file.
    outfile << data << endl;

    cout << "Enter your age: "; 
    cin >> data; 
    cin.ignore();

    // again write inputted data into the file.
    outfile << data << endl;
    // close the opened file.
    outfile.close();

    // open a file in read mode.
    ifstream infile; 
    infile.open("afile.dat");

    cout << "Reading from the file" << endl; 
    infile >> data;

    // write the data at the screen. 
    cout << data << endl;

    // again read the data from the file and display it. 
    infile >> data; 
    cout << data << endl;

    // close the opened file.
    infile.close();

    return 0;

Then I’m confused about the three open mode for file – app, out, trunc.

If for name I enter “Zara” and age “9”, the output should be “9ara”. However, it is not. It is “Zara 9”.

Upvotes: 12

Views: 40151

Answers (2)

Inot
Inot

Reputation: 133

Just a little correction to Barmar's answer. I think that the type ofstream implies not only the ios::out, but also the ios::trunc (and I'm not sure, but the ios::out could also imply the ios::trunc).

Here's the concrete example:

ofstream fich;
    fich.open("archivo.txt");
    for (unsigned i = 0; i < ag.n_pers && !fich.fail(); ++i) {
        escribir_persona(fich, ag.pers[i]);
    }
    if (fich.fail()) {
        ok = ERROR;
    }
    else {
        ok = OK;
    }
    fich.close();

When I call this function, the data of the file is completely overwrited (even if the data to write is less than that which was writen previously), and if the data to write is empty, this just deletes everything in the file.

Upvotes: 7

Barmar
Barmar

Reputation: 781210

ios::out is the default mode for std::ofstream, it means that output operations can be used (i.e. you can write to the file).

ios::app (short for append) means that instead of overwriting the file from the beginning, all output operations are done at the end of the file. This is only meaningful if the file is also open for output.

ios::trunc (short for truncate) means that when the file is opened, the old contents are immediately removed. Again, this is only meaningful if the file is also open for output.

Your code just uses the default ios::out mode. So it starts writing from the beginning of the file, but doesn't remove the old contents. So the new contents will overlay what's already there -- if the file is originally 10 bytes long, and you write 3 bytes, the result will be the 3 bytes you write followed by the remaining 7 bytes of the original contents. More concretely, if the file originally contains:

Firstname Lastname
30

and you write FN LN and then 20 (with newlines after each), the resulting file will look like:

FN LN
20
 Lastname
30

because you only overwrite the first 9 bytes of the file (assuming Unix-style newlines).

Once you've opened the file, all outputs to the file are written sequentially after each other, unless you use outfile.seekp() to go to a different location. It doesn't go back to the beginning of the file for each thing you write. seekp() has no effect if the ios::app is used; then every write goes at the end of the file.

Upvotes: 22

Related Questions