C++ Tutorial
C++ Files
fstream reads and writes files. Always check that the file opened before you use it.
Disk instead of the console
cout writes to the screen. Files keep data after the program ends. In C++ you include<fstream>. ofstream writes. ifstream reads. Both are streams, so<< and >> look like cout and cin.
StudyGrid /cpp/try compiles and runs in a sandbox with no real disk. ofstream andifstream still compile, but opening a path often fails. Download the .cpp and run it with local g++ when you want a file to actually appear. The examples below always check is_open().
What the editor can still run
This program is a complete main. It compiles in the C++ editor. It does not need a file. Use it to confirm the chapter examples open in /cpp/try, then download a file example for a real disk.
Example
#include <iostream>
using namespace std;
int main() {
cout << "File streams need a disk." << endl;
cout << "On StudyGrid, download the .cpp and compile with g++." << endl;
return 0;
}ofstream writes
Construct an ofstream with a path. If the file opens, send text with <<. If it does not, print an error and skip the write. Never assume the path worked.
Example
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream out("notes.txt");
if (!out.is_open()) {
cout << "could not open notes.txt for writing" << endl;
return 0;
}
out << "first line" << endl;
out << "second line" << endl;
out.close();
cout << "wrote notes.txt" << endl;
return 0;
}On a machine with a filesystem this creates notes.txt in the working directory. In/cpp/try you should see the “could not open” message. That is the check doing its job, not a broken example.
ifstream reads
ifstream opens an existing file. Check is_open() the same way. Then read line by line with getline, or token by token with >>.
Example
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream in("notes.txt");
if (!in.is_open()) {
cout << "could not open notes.txt for reading" << endl;
return 0;
}
string line;
while (getline(in, line)) {
cout << line << endl;
}
in.close();
return 0;
}Run this locally after the write example, in the same folder. The loop stops when there are no more lines. Closing is polite; the destructor also closes the file when in goes out of scope.
A stream that is not a file
stringstream lives in memory. It uses the same << and >> as a file, so you can practice stream code in the browser. Include <sstream>.
Example
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
stringstream ss;
ss << "3 4";
int a = 0;
int b = 0;
ss >> a >> b;
cout << a + b << endl;
return 0;
}Output is 7. Same idea as reading two numbers from a file, without touching disk. When you are ready for a real file, swap stringstream for ifstream and keep the >> lines.
Open, check, then use
| Type | Header | Typical use |
|---|---|---|
| ofstream | <fstream> | Create or overwrite a file, then << |
| ifstream | <fstream> | Open an existing file, then >> or getline |
| fstream | <fstream> | Read and write the same file (later) |
| stringstream | <sstream> | Same operators, no disk |
- Always test
is_open()(or the stream in a boolean context) before reading or writing. - A failed open is not a crash if you handle it. Using a closed stream is wasted work and empty reads.
- Paths are relative to the process working directory unless you pass an absolute path.
Local compile for real files
Save a .cpp from this page. In that folder run g++ -std=c++17 files.cpp -o files then./files (or files.exe on Windows). You should see notes.txt appear next to the program. Next: what to do when an operation cannot continue — exceptions.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the C++ editor at /cpp/try. Change one measurement and check whether the result still has the right unit.
Chemistry
A titration table on stdout
Two titres 24.8 mL and 25.1 mL are typical concordant-ish burette readings. You would still average only the ones that agree within 0.1 mL in a real write-up. This listing only records them.
cout is a stream. ofstream is the same idea aimed at a disk file.
Example
#include <iostream>
using namespace std;
int main() {
cout << "titration, HCl vs NaOH" << endl;
cout << "run 1: 24.8 mL" << endl;
cout << "run 2: 25.1 mL" << endl;
return 0;
}Physics
A drop-test CSV
s = ½ g t² again: t = 0, 1, 2 s maps to 0, 4.91, 19.62 m. A CSV is how you later plot that in a spreadsheet. If the open fails, print that fact; do not write on a dead stream.
Example
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream fp("drop.csv");
if (!fp) {
cout << "could not write drop.csv" << endl;
return 1;
}
fp << "t_s,s_m" << endl;
fp << "0,0" << endl;
fp << "1,4.91" << endl;
fp << "2,19.62" << endl;
cout << "wrote drop.csv" << endl;
return 0;
}