In C++, we can interact with files. We always #include <fstream>, and:

  • Open files with: ifstream inFile("myfile"), as in “input file stream” with name inFile.
    • And we should ideally close() the file before we open() another one.
    • By default, this overwrites all existing content on the file, otherwise a new file is created.
    • Otherwise, we can open to append content, i.e., what we write adds to the end of the existing file. Use: outFile.open("foo.txt", ios::app)
#include <fstream>
ifstream inFile;
inFile.open("myFile");      // searches in current dir
inFile.open("dir/myFile");  // relative path, i.e., from the current directory
							// will search for dir, one level down
inFile.open("../myFile");   // relative path, in parent directory
inFile.open("/etc/myFile"); // absolute path, starts at root directory and moves down
  • Read from a file:
int a, b, c;
inputFile >> a >> b >> c;
  • Output to a file:
ofstream outFile("myFile.txt");

Methods

  • And closing files: inFile.close()
  • For file output, we can:
ofstream outFile;
outFile.open("myOutFile");
 
int x = 63;
outFile << "x = " << x << endl;
 
outFile.close();
  • When we reach the end of the file, we use: inFile.eof(), which evaluates to true if we reached the end.
  • fail() returns true if there’s any error, checks if there’s a flag
  • inFile is an object, has an error flag
  • You can use this approach on inFile, cin, cout, outFile or any other stream

Buffering

Output is not immediately written to a file, instead temporarily stored in a buffer, then written out to the file periodically in chunks. What this means is that our results don’t show up immediately. Why does this happen? Writing to the disk is pretty slow.

We sometimes flush out the buffer. With respect to file outputs, we can use outFile.flush() or outFile << endl.

Input

Inputs are also buffered. No access to input data until user uses the ENTER key. Data is extracted character-by-character or byte-by-byte. Strings are read until a whitespace. For other types, it reads char-by-char until a conversion isn’t possible. See below.

Whitespaces are skipped, i.e., , \t, \n, etc.

// if input "  2.3  56.4 \n"
int a; float b;
cin >> a; // a = 2
cin >> b; // b = 0.3

Things that could go wrong

Some things can go wrong:

  • The file doesn’t exist or cannot open
  • Variables of a certain type cannot be read (i.e., we get some other type)

So we have to detect errors and be able to handle them:

if (inFile.fail()) {
	cerr << "Cannot open file: inputFile" << endl;
	return 1;
}

Alternatively:

while (inFile.fail()) {
	inFile.clear(); // clears error flag of inFile
	inFile.ignore(1000, '\n'); // ignores 1000 chars or all input up to end of line
	inFile >> a;
}