L11 C++ IO
Dynamically allocating an array of pointers is a lot more memory efficient than an array of objects
8 bytes per address (pointer), much more efficient than an object (probably more than 8 bytes)
File IO using ifstream and ofstream
coutandcinare objectscoutfromostreamclasscinfromistreamclass
- we can also produce output/take input from a file
ifstreamlets us write from an input fileofstreamlets us write to an output file
- we can do this for any file type, even files with no extension
example: program that writes to a file
#include <iostream>
#include <fstream>
int main(void) {
// file output
ofstream outFile("File.txt");
// ofstream is the class name
// outFile is our own name for the object
outFile << "Hello" << endl;
outFile.close(); // saves to the file
// once we close, we cannot write to the file again
return 0;
}
Usage of
ofstream
When a file is called using ofstream:
- If file does not exist, it will be created
- If file exists, the content inside will be overwritten
- If file exist, and we want to append to content:
ofstream outFile("file.txt", ios::app);
example: read from an input file
#include <fstream>
using namespace std;
int main(void) {
ifstream inFile("inFile.txt");
// creates object inFile and opens file inFile.txt
// or we can seperate them:
ifstream inFile;
inFile.open("inFile.txt");
int num1, num2;
inFile >> num1 >> num2; // reading two integers from inFile
cout << "Sum is " << num1 + num2 << endl;
}
working with other directories
Everything is a relative path from the current directory
File.txtsearches for the file in the same directory../File.txtsearches for the file in the parent directory/v/prof/emarasal/Desktop/ECE244/lecture11/File.txtis an absolute path
This follows the regular unix-like file paths.
buffering
It is slow to write output to a file/terminal compared to writing it in a "buffer"
- buffer is a place in memory that is quick to read/write from
- when we do
outfile << "hello";we are writing to buffer before we write to the file
flushing from buffer (output)
- new line
endlwill flush output from buffer to file - or we can use
outFile.flush()orcout.flush()cout.flush()is for terminal
outFile.close()also flushes everything automatically (obviously)
for inputs, the
flushing from buffer (input)
int x, y;
cin >> x >> y;
input is 13 4\n
cinprocesses input from bugger after new line\nis enteredcinignores white spaces if it's only looking for anintcinread 13 into x, ignores white space between 13 and 4, and reads 4 into y.
problem with the above example
if input is instead 13.4\n:
cinreads up to 13 into x. The.is not processed, as it is not part of anint.cinwill not read any further; it fails because it tries to read.tox- this calls
cin.fail() - after C++ 2011, whatever gets read while
coutfails silently, that variable gets zeroed out:intbecomes0charbecomes ASCII for0- etc.
- HOWEVER, the buffer is NOT affected
- this calls
- To detect these errors we can use:
inFile.fail()orcin.fail() - To handle these errors we can use:
cin.clear()orinFile.clear()to reset the fail flag
what should you do before taking input?
- Always check if the fail flag is raised when taking input
- If fail flag is raised, then handle the error
To check if a fail flag is raised:
if (inputFile.fail()) {
cerr << "Cannot" << endl;
return 1; // return 1
}
Note: cerr is an output stream similar to cout, but it is unbuffered, so it shows up immediately in terminal.
Then, handle the error:
- we can use
cin.clear()to clear the fail flags - then, we can use
cin.ignore(int n, char ch);to discard a certain number of characters- discard
ncharacters, or discard up toch- whichever comes first
- discard