listings-Chap27-README-onepage.md
Listings of Chap27.docx
This is the list of listings on one page. You can also view a linked summary.
Listing 27.1: Returning the stream by reference allows chaining.
Book listing lst-0003-book.cpp:
// https://godbolt.org/z/WaEGdnWvq
#include <iostream> // cin, cout
int main() {
int val1, val2;
std::cout << "Please enter 2 int values: ";
std::cin >> val1 >> val2;
std::cout << val1 << " : " << val2 << std::endl;
}
Godbolt Listing lst-0003-godb.cpp, https://godbolt.org/z/WaEGdnWvq:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/WaEGdnWvq
#include <iostream> // cin, cout
int main() {
int val1, val2;
std::cout << "Please enter 2 int values: ";
std::cin >> val1 >> val2;
std::cout << val1 << " : " << val2 << std::endl;
}
Listing 27.2: Unformatted input from streams.
Book listing lst-0005-book.cpp:
// https://godbolt.org/z/MaEzcccTG
#include <iostream>
using std::cout; using std::cin; using std::endl;
int main() {
const unsigned int MAX = 10;
char buffer[MAX] = {0};
cout << "Input getline : ";
cin.getline(buffer, MAX);
cout << std::cin.gcount()
<< " characters were read\n";
for(auto c : buffer) {
if(c && c!='\0') cout.put(c);
}
cin.ignore(MAX, '\n');
cout << "\nMake input (end with .) : ";
char ch=0;
while(cin.get(ch)) {
if(ch == '.') break;
cout.put(ch);
}
cout << "Input ended" << endl;
}
Godbolt Listing lst-0005-godb.cpp, https://godbolt.org/z/MaEzcccTG:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/MaEzcccTG
#include <iostream>
using std::cout; using std::cin; using std::endl;
int main() {
const unsigned int MAX = 10;
char buffer[MAX] = {0};
cout << "Input getline : ";
cin.getline(buffer, MAX);
cout << std::cin.gcount()
<< " characters were read\n";
for(auto c : buffer) {
if(c && c!='\0') cout.put(c);
}
cin.ignore(MAX, '\n');
cout << "\nMake input (end with .) : ";
char ch=0;
while(cin.get(ch)) {
if(ch == '.') break;
cout.put(ch);
}
cout << "Input ended" << endl;
}
Listing 27.3: State checks for streams.
Book listing lst-0007-book.cpp:
// https://godbolt.org/z/exKMv8646
#include <fstream>
#include <iostream>
using std::cout; using std::cin; using std::ofstream;
void checkIOstate(std::ios& stream) {
if( stream.good() ) {
cout << "All good\n";
} else if( stream.bad() ) {
cout << "Fatal error\n";
} else if( stream.fail()) {
cout << "I/O error\n";
if( stream.eof()) {
cout << "End of stream reached\n";
}
}
stream.clear();
}
int main() {
int val=0;
cout << "Enter value: ";
cin >> val;
checkIOstate( cin );
std::ifstream file;
file.open("nonexistent.text");
checkIOstate(file);
std::fstream fstr;
fstr.open("newFile.txt",
ofstream::out | ofstream::in
| ofstream::binary | ofstream::trunc);
fstr << "Text in the file\n";
fstr.seekp(std::ios_base::beg);
char ch;
while( fstr.good()) {
fstr.get(ch);
if(fstr.good()) cout.put(ch);
}
checkIOstate(fstr);
}
Godbolt Listing lst-0007-godb.cpp, https://godbolt.org/z/exKMv8646:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/exKMv8646
#include <fstream>
#include <iostream>
using std::cout; using std::cin; using std::ofstream;
void checkIOstate(std::ios& stream) {
if( stream.good() ) {
cout << "All good\n";
} else if( stream.bad() ) {
cout << "Fatal error\n";
} else if( stream.fail()) {
cout << "I/O error\n";
if( stream.eof()) {
cout << "End of stream reached\n";
}
}
stream.clear();
}
int main() {
int val=0;
cout << "Enter value: ";
cin >> val;
checkIOstate( cin );
std::ifstream file;
file.open("nonexistent.text");
checkIOstate(file);
std::fstream fstr;
fstr.open("newFile.txt",
ofstream::out | ofstream::in
| ofstream::binary | ofstream::trunc);
fstr << "Text in the file\n";
fstr.seekp(std::ios_base::beg);
char ch;
while( fstr.good()) {
fstr.get(ch);
if(fstr.good()) cout.put(ch);
}
checkIOstate(fstr);
}
Listing 27.4: Operator “bool” of streams.
Book listing lst-0008-book.cpp:
// https://godbolt.org/z/Mr6E3Ez48
#include <iostream>
int main() {
unsigned int val;
std::cout << "Enter value: ";
std::cin >> val;
if( std::cin ) { // operator bool()
/* ... */ // Input correct
} else {
std::cout << "Error with std::cin\n"; // Error with input
}
}
Godbolt Listing lst-0008-godb.cpp, https://godbolt.org/z/Mr6E3Ez48:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/Mr6E3Ez48
#include <iostream>
int main() {
unsigned int val;
std::cout << "Enter value: ";
std::cin >> val;
if( std::cin ) { // operator bool()
/* ... */ // Input correct
} else {
std::cout << "Error with std::cin\n"; // Error with input
}
}
Listing 27.5: Outputting a Boolean as text or a number.
Book listing lst-0009-book.cpp:
// https://godbolt.org/z/s1csa51z9
#include <iostream>
#include <iomanip>
using std::cin; using std::cout; using std::endl;
void f(bool b) {
cout << b << endl; // Output: true
}
int main () {
bool b=true;
cout << std::boolalpha << b << endl; // Output: true
b=false;
cout << b << endl; // Output: false
f(true);
cout << std::noboolalpha << b << endl; // Output: 0
b=true;
cout << b << endl; // Output: 1
}
Godbolt Listing lst-0009-godb.cpp, https://godbolt.org/z/s1csa51z9:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/s1csa51z9
#include <iostream>
#include <iomanip>
using std::cin; using std::cout; using std::endl;
void f(bool b) {
cout << b << endl; // Output: true
}
int main () {
bool b=true;
cout << std::boolalpha << b << endl; // Output: true
b=false;
cout << b << endl; // Output: false
f(true);
cout << std::noboolalpha << b << endl; // Output: 0
b=true;
cout << b << endl; // Output: 1
}
Listing 27.6: Number formats in output.
Book listing lst-0011-book.cpp:
// https://godbolt.org/z/bEKaYdssE
#include <iostream>
#include <ios>
using std::cout; using std::endl;
void f() {
int val = 100;
cout << val << endl; // Output: 0x64
}
int main() {
int val = 255;
cout << std::showbase;
cout << std::dec << val << endl; // Output: 255
cout << std::hex << val << endl; // Output: 0xff
f();
cout << std::oct << val << endl; // Output: 0377
cout << val << std::endl; // Output: 0377
}
Godbolt Listing lst-0011-godb.cpp, https://godbolt.org/z/bEKaYdssE:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/bEKaYdssE
#include <iostream>
#include <ios>
using std::cout; using std::endl;
void f() {
int val = 100;
cout << val << endl; // Output: 0x64
}
int main() {
int val = 255;
cout << std::showbase;
cout << std::dec << val << endl; // Output: 255
cout << std::hex << val << endl; // Output: 0xff
f();
cout << std::oct << val << endl; // Output: 0377
cout << val << std::endl; // Output: 0377
}
Listing 27.7: Different ways to pad output.
Book listing lst-0012-book.cpp:
// https://godbolt.org/z/TMdzrjvhd
#include <iostream>
#include <ios> // left, right, internal
#include <iomanip> // setw
using std::cout; using std::endl;
int main() {
int val = -1000;
cout << std::setw(10) << std::internal
<< val << endl;
cout << std::setw(10) << std::left << val << endl;
cout << std::setw(10) << std::right
<< val << endl;
}
Godbolt Listing lst-0012-godb.cpp, https://godbolt.org/z/TMdzrjvhd:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/TMdzrjvhd
#include <iostream>
#include <ios> // left, right, internal
#include <iomanip> // setw
using std::cout; using std::endl;
int main() {
int val = -1000;
cout << std::setw(10) << std::internal
<< val << endl;
cout << std::setw(10) << std::left << val << endl;
cout << std::setw(10) << std::right
<< val << endl;
}
Listing 27.8: Number formats in output.
Book listing lst-0013-book.cpp:
// https://godbolt.org/z/sYK8oT33x
#include <iostream>
#include <ios> // left, right, internal
#include <iomanip> // setw
using std::cout; using std::endl;
int main() {
double dval = 3.14159;
std::ios_base::fmtflags ff(std::ios::scientific|std::ios::uppercase);
cout << std::setiosflags(ff);
cout << dval << endl; // Output: 3.141590E+00
cout << std::resetiosflags(ff) << dval << endl; // Output: 3.14159
cout << std::setprecision(3) << dval << endl; // Output: 3.14
cout << std::setw(10);
cout << std::setfill( '*' ) << 1246 << endl; // Output: ******1246
}
Godbolt Listing lst-0013-godb.cpp, https://godbolt.org/z/sYK8oT33x:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/sYK8oT33x
#include <iostream>
#include <ios> // left, right, internal
#include <iomanip> // setw
using std::cout; using std::endl;
int main() {
double dval = 3.14159;
std::ios_base::fmtflags ff(std::ios::scientific|std::ios::uppercase);
cout << std::setiosflags(ff);
cout << dval << endl; // Output: 3.141590E+00
cout << std::resetiosflags(ff) << dval << endl; // Output: 3.14159
cout << std::setprecision(3) << dval << endl; // Output: 3.14
cout << std::setw(10);
cout << std::setfill( '*' ) << 1246 << endl; // Output: ******1246
}
Listing 27.9: Custom manipulators.
Book listing lst-0014-book.cpp:
// https://godbolt.org/z/z8zc3ocd5
#include <iostream>
#include <ios> // left, right, internal
#include <iomanip> // setw
using std::cout; using std::cin; using std::endl;
std::ostream& tabl(std::ostream& os) {
os << '\t';
return os;
}
std::istream& firstNum(std::istream& is) {
char ch;
is.get(ch);
if( (ch >= '0') && (ch <= '9') ) {
std::cin.putback(ch);
}
return is;
}
int main() {
int val=0;
cout << "Text1" << tabl << "Text2" << endl; // Output: Text1 (tab) Text2
cout << "Make an input: ";
cin >> firstNum >> val;
cout << val << std::endl; // Output: 12345
}
Godbolt Listing lst-0014-godb.cpp, https://godbolt.org/z/z8zc3ocd5:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/z8zc3ocd5
#include <iostream>
#include <ios> // left, right, internal
#include <iomanip> // setw
using std::cout; using std::cin; using std::endl;
std::ostream& tabl(std::ostream& os) {
os << '\t';
return os;
}
std::istream& firstNum(std::istream& is) {
char ch;
is.get(ch);
if( (ch >= '0') && (ch <= '9') ) {
std::cin.putback(ch);
}
return is;
}
int main() {
int val=0;
cout << "Text1" << tabl << "Text2" << endl; // Output: Text1 (tab) Text2
cout << "Make an input: ";
cin >> firstNum >> val;
cout << val << std::endl; // Output: 12345
}
Listing 27.10: Manipulator as lambda.
Book listing lst-0016-book.cpp:
#include <iostream>
using std::cout; using std::endl;
int main() {
auto ddash = [](auto &os) -> std::ostream& { return os << "--"; };
cout << "Text1" << ddash << "Text2" << endl; // Output: Text1--Text2
}
Listing 27.11: Manipulators with parameters.
Book listing lst-0017-book.cpp:
// https://godbolt.org/z/KKE6nWT49
#include <iostream>
using std::cout; using std::endl;
class dendl { // Dots followed by newline
int dendl_;
public:
dendl(int n=1)
: dendl_{n} {}
std::ostream& operator()(std::ostream& os) const { // Functor
for(int i=0; i<dendl_; ++i) os << '.';
return os << '\n';
}
};
std::ostream& operator<<( std::ostream& os, const dendl& elem) {
return elem(os);
}
int main() {
cout << "Text1" << dendl(4); // Output: Text1....
cout << "Text2" << dendl(2); // Output: Text2..
cout << "Text3" << dendl(); // Output: Text3.
}
Godbolt Listing lst-0017-godb.cpp, https://godbolt.org/z/KKE6nWT49:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/KKE6nWT49
#include <iostream>
using std::cout; using std::endl;
class dendl { // Dots followed by newline
int dendl_;
public:
dendl(int n=1)
: dendl_{n} {}
std::ostream& operator()(std::ostream& os) const { // Functor
for(int i=0; i<dendl_; ++i) os << '.';
return os << '\n';
}
};
std::ostream& operator<<( std::ostream& os, const dendl& elem) {
return elem(os);
}
int main() {
cout << "Text1" << dendl(4); // Output: Text1....
cout << "Text2" << dendl(2); // Output: Text2..
cout << "Text3" << dendl(); // Output: Text3.
}
Listing 27.12: Directly influencing format.
Book listing lst-0019-book.cpp:
// https://godbolt.org/z/csbPMYM19
#include <iostream>
#include <ios> // hex, dec
using std::cout; using std::endl;
int main() {
int val = 255;
cout << std::showbase << std::hex << val << endl; // Output: 0xff
cout << std::noshowbase << std::dec << val << endl; // Output: 255
}
Godbolt Listing lst-0019-godb.cpp, https://godbolt.org/z/csbPMYM19:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/csbPMYM19
#include <iostream>
#include <ios> // hex, dec
using std::cout; using std::endl;
int main() {
int val = 255;
cout << std::showbase << std::hex << val << endl; // Output: 0xff
cout << std::noshowbase << std::dec << val << endl; // Output: 255
}
Listing 27.13: Influencing format with “setf” and “unsetf”.
Book listing lst-0020-book.cpp:
// https://godbolt.org/z/1xzzMdjdM
#include <iostream>
using std::cout; using std::endl;
int main() {
int val = 255;
cout.setf(std::ios_base::hex, std::ios_base::basefield);
cout.setf(std::ios_base::showbase);
cout << val << std::endl; // Output: 0xff
cout.unsetf(std::ios_base::showbase);
cout.setf(std::ios_base::dec, std::ios_base::basefield);
cout << val << std::endl; // Output: 255
}
Godbolt Listing lst-0020-godb.cpp, https://godbolt.org/z/1xzzMdjdM:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/1xzzMdjdM
#include <iostream>
using std::cout; using std::endl;
int main() {
int val = 255;
cout.setf(std::ios_base::hex, std::ios_base::basefield);
cout.setf(std::ios_base::showbase);
cout << val << std::endl; // Output: 0xff
cout.unsetf(std::ios_base::showbase);
cout.setf(std::ios_base::dec, std::ios_base::basefield);
cout << val << std::endl; // Output: 255
}
Listing 27.14: Saving and restoring flags.
Book listing lst-0021-book.cpp:
// https://godbolt.org/z/4MY1Yznv9
#include <iostream>
using std::cout; using std::endl;
int main() {
int val = 255;
std::ios::fmtflags ff = std::cout.flags();
cout.flags(std::ios::hex | std::ios::showbase);
cout << val << endl; // Output: 0xff
cout.flags(ff);
cout << val << endl; // Output: 255
}
Godbolt Listing lst-0021-godb.cpp, https://godbolt.org/z/4MY1Yznv9:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/4MY1Yznv9
#include <iostream>
using std::cout; using std::endl;
int main() {
int val = 255;
std::ios::fmtflags ff = std::cout.flags();
cout.flags(std::ios::hex | std::ios::showbase);
cout << val << endl; // Output: 0xff
cout.flags(ff);
cout << val << endl; // Output: 255
}
Listing 27.15: Opening and creating files.
Book listing lst-0022-book.cpp:
// https://godbolt.org/z/o7YP7or8s
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::string name = "textfile.txt";
std::ifstream file01;
file01.open(name);
if( file01.fail() ) {
std::cout << "Could not open " << name << "\n";
}
std::ofstream file02("data.dat");
if( file02.good() ) {
std::cout << "data.dat opened or created\n";
}
std::fstream file03;
file03.open("database.db");
if( !file03 ) {
std::cout << "Could not open database.db\n";
}
}
Godbolt Listing lst-0022-godb.cpp, https://godbolt.org/z/o7YP7or8s:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/o7YP7or8s
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::string name = "textfile.txt";
std::ifstream file01;
file01.open(name);
if( file01.fail() ) {
std::cout << "Could not open " << name << "\n";
}
std::ofstream file02("data.dat");
if( file02.good() ) {
std::cout << "data.dat opened or created\n";
}
std::fstream file03;
file03.open("database.db");
if( !file03 ) {
std::cout << "Could not open database.db\n";
}
}
Listing 27.16: Additional flags when opening files.
Book listing lst-0023-book.cpp:
// https://godbolt.org/z/GoPddTWq6
#include <fstream>
#include <iostream>
using std::cout;
int main() {
std::ofstream file01("testfile.txt", std::ios::out|std::ios::app);
if(file01.fail()) {
cout << "Could not open testfile.txt\n";
} else {
cout << "ok.\n";
}
std::fstream file02;
file02.open("database.db", std::ios::out|std::ios::trunc);
if( !file02 ) {
cout << "Could not open database.db\n";
} else {
cout << "ok.\n";
}
}
Godbolt Listing lst-0023-godb.cpp, https://godbolt.org/z/GoPddTWq6:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/GoPddTWq6
#include <fstream>
#include <iostream>
using std::cout;
int main() {
std::ofstream file01("testfile.txt", std::ios::out|std::ios::app);
if(file01.fail()) {
cout << "Could not open testfile.txt\n";
} else {
cout << "ok.\n";
}
std::fstream file02;
file02.open("database.db", std::ios::out|std::ios::trunc);
if( !file02 ) {
cout << "Could not open database.db\n";
} else {
cout << "ok.\n";
}
}
Listing 27.17: Explicitly closing a file stream.
Book listing lst-0024-book.cpp:
// https://godbolt.org/z/TMzdWhE51
#include <fstream>
#include <iostream>
int main() {
std::ofstream file01("data.db");
if( file01.fail() ) {
std::cout << "Could not open data.db\n";
} else {
std::cout << "ok.\n";
}
file01 << "Text for the file\n";
if( file01.is_open()) {
file01.close();
}
file01.open("data001.db");
// Automatically:
{
std::ofstream file02("data002.db");
} // from here file02 is closed
} // from here file01 is also closed
Godbolt Listing lst-0024-godb.cpp, https://godbolt.org/z/TMzdWhE51:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/TMzdWhE51
#include <fstream>
#include <iostream>
int main() {
std::ofstream file01("data.db");
if( file01.fail() ) {
std::cout << "Could not open data.db\n";
} else {
std::cout << "ok.\n";
}
file01 << "Text for the file\n";
if( file01.is_open()) {
file01.close();
}
file01.open("data001.db");
// Automatically:
{
std::ofstream file02("data002.db");
} // from here file02 is closed
} // from here file01 is also closed
Listing 27.18: Reading and writing with files.
Book listing lst-0025-book.cpp:
// https://godbolt.org/z/3756v8rzK
#include <fstream>
#include <iomanip> // setw
#include <iostream>
int main() {
std::ofstream file("data.dat");
if( !file ) {
std::cout << "Could not open data.dat\n";
return 1;
}
file << std::setw(10) << std::setfill( '*' )
<< 1234 << std::endl;
}
Godbolt Listing lst-0025-godb.cpp, https://godbolt.org/z/3756v8rzK:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/3756v8rzK
#include <fstream>
#include <iomanip> // setw
#include <iostream>
int main() {
std::ofstream file("data.dat");
if( !file ) {
std::cout << "Could not open data.dat\n";
return 1;
}
file << std::setw(10) << std::setfill( '*' )
<< 1234 << std::endl;
}
Listing 27.19: Byte-wise reading and writing.
Book listing lst-0026-book.cpp:
// https://godbolt.org/z/sjaGaq48v
#include <fstream>
#include <iomanip> // setw
#include <iostream>
int main() {
std::ifstream file("data.dat");
if( !file ) {
std::cout << "Error opening file\n";
return 1;
}
char ch;
while(file.get(ch) ) {
std::cout.put(ch);
}
if( file.eof() ) {
file.clear();
}
file.close();
}
Godbolt Listing lst-0026-godb.cpp, https://godbolt.org/z/sjaGaq48v:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/sjaGaq48v
#include <fstream>
#include <iomanip> // setw
#include <iostream>
int main() {
std::ifstream file("data.dat");
if( !file ) {
std::cout << "Error opening file\n";
return 1;
}
char ch;
while(file.get(ch) ) {
std::cout.put(ch);
}
if( file.eof() ) {
file.clear();
}
file.close();
}
Listing 27.20: Copying a file byte by byte.
Book listing lst-0027-book.cpp:
#include <fstream>
#include <iostream>
using std::cout;
int main() {
std::ifstream file("data.dat");
if( !file ) { /* Error */ cout << "ERR\n"; return 1; }
std::ofstream filecopy("backup.dat");
if( !filecopy ) { /* Error */ cout << "ERR\n"; return 1; }
char ch;
while(file.get(ch) ) {
filecopy.put(ch);
}
}
Listing 27.21: Line-by-line reading and writing.
Book listing lst-0028-book.cpp:
// https://godbolt.org/z/hPaz3a3sE
#include <fstream>
#include <iostream>
using std::cout;
int main() {
std::ifstream file("44fstream07.cpp");
if( !file ) { /* Error */ cout << "ERR\n"; return 1; }
std::ofstream filecopy("backup.cpp");
if( !filecopy ) { /* Error */ cout << "ERR\n"; return 1; }
std::string buffer;
while( getline(file, buffer) ) {
filecopy << buffer << std::endl;
cout << buffer << std::endl;
}
if( file.eof() ) {
file.clear();
}
}
Godbolt Listing lst-0028-godb.cpp, https://godbolt.org/z/hPaz3a3sE:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/hPaz3a3sE
#include <fstream>
#include <iostream>
using std::cout;
int main() {
std::ifstream file("44fstream07.cpp");
if( !file ) { /* Error */ cout << "ERR\n"; return 1; }
std::ofstream filecopy("backup.cpp");
if( !filecopy ) { /* Error */ cout << "ERR\n"; return 1; }
std::string buffer;
while( getline(file, buffer) ) {
filecopy << buffer << std::endl;
cout << buffer << std::endl;
}
if( file.eof() ) {
file.clear();
}
}
Listing 27.22: Block-wise reading and writing with “read” and “write”.
Book listing lst-0029-book.cpp:
// https://godbolt.org/z/P6MPabsKc
#include <fstream>
#include <iostream>
#include <vector>
using std::cout;
int main() {
std::ifstream file("testfile.txt", std::ios::binary);
if( !file ) { /* Error */ cout <<"ERR1\n"; return 1; }
std::ofstream filecopy("backup.dat", std::ios::binary);
if( !filecopy ) { /* Error */ return 1; }
file.seekg(0, std::ios::end);
auto size = file.tellg();
cout << "File size: " << size << " bytes\n";
file.seekg(0, std::ios::beg); // Important!
std::vector<char> buffer(size);
file.read(buffer.data(), size);
if( !file ) { cout << "Error during read...\n"; return 1;}
cout << "Read: " << file.gcount() << " bytes\n";
filecopy.write( buffer.data(), size );
if( !filecopy ) { cout << "Error during write...\n"; return 1;}
}
Godbolt Listing lst-0029-godb.cpp, https://godbolt.org/z/P6MPabsKc:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/P6MPabsKc
#include <fstream>
#include <iostream>
#include <vector>
using std::cout;
int main() {
std::ifstream file("testfile.txt", std::ios::binary);
if( !file ) { /* Error */ cout <<"ERR1\n"; return 1; }
std::ofstream filecopy("backup.dat", std::ios::binary);
if( !filecopy ) { /* Error */ return 1; }
file.seekg(0, std::ios::end);
auto size = file.tellg();
cout << "File size: " << size << " bytes\n";
file.seekg(0, std::ios::beg); // Important!
std::vector<char> buffer(size);
file.read(buffer.data(), size);
if( !file ) { cout << "Error during read...\n"; return 1;}
cout << "Read: " << file.gcount() << " bytes\n";
filecopy.write( buffer.data(), size );
if( !filecopy ) { cout << "Error during write...\n"; return 1;}
}
Listing 27.23: Block-wise reading and writing with a helper class.
Book listing lst-0030-book.cpp:
// https://godbolt.org/z/b3W48s86z
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::string;
class DataClass {
std::string text_;
int data_;
public:
DataClass(string t="", int i=0)
: text_{t}, data_{i} {}
std::ostream& write(std::ostream& os) const {
os << text_ << std::ends;
os.write(reinterpret_cast<const char*>(&data_), sizeof(data_));
return os;
}
std::istream& read(std::istream& is) {
std::getline(is, text_, '\0');
is.read(reinterpret_cast<char*>(&data_), sizeof(data_));
return is;
}
std::ostream& print(std::ostream& os) {
return os << text_ << " : " << data_ << std::endl;
}
};
int main() {
std::ofstream file_w("data.dat", std::ios::binary);
if( !file_w) { cout << "Error opening file\n"; return 1; }
std::vector<DataClass> vec_dat;
vec_dat.push_back(DataClass("A text", 123));
vec_dat.push_back(DataClass("More text", 321));
vec_dat.emplace_back("Much more text", 333);
for(const auto &elem : vec_dat){
elem.write(file_w);
}
file_w.close();
std::ifstream file_r("data.dat", std::ios::binary);
if( !file_r) { cout << "Error opening file\n"; return 1; }
DataClass dat_r;
while( file_r ) {
dat_r.read(file_r);
if( file_r.eof()) break;
dat_r.print(cout);
}
}
Godbolt Listing lst-0030-godb.cpp, https://godbolt.org/z/b3W48s86z:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/b3W48s86z
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::string;
class DataClass {
std::string text_;
int data_;
public:
DataClass(string t="", int i=0)
: text_{t}, data_{i} {}
std::ostream& write(std::ostream& os) const {
os << text_ << std::ends;
os.write(reinterpret_cast<const char*>(&data_), sizeof(data_));
return os;
}
std::istream& read(std::istream& is) {
std::getline(is, text_, '\0');
is.read(reinterpret_cast<char*>(&data_), sizeof(data_));
return is;
}
std::ostream& print(std::ostream& os) {
return os << text_ << " : " << data_ << std::endl;
}
};
int main() {
std::ofstream file_w("data.dat", std::ios::binary);
if( !file_w) { cout << "Error opening file\n"; return 1; }
std::vector<DataClass> vec_dat;
vec_dat.push_back(DataClass("A text", 123));
vec_dat.push_back(DataClass("More text", 321));
vec_dat.emplace_back("Much more text", 333);
for(const auto &elem : vec_dat){
elem.write(file_w);
}
file_w.close();
std::ifstream file_r("data.dat", std::ios::binary);
if( !file_r) { cout << "Error opening file\n"; return 1; }
DataClass dat_r;
while( file_r ) {
dat_r.read(file_r);
if( file_r.eof()) break;
dat_r.print(cout);
}
}
Listing 27.24: Synchronizing output between threads with “osyncstream”.
Book listing lst-0032-book.cpp:
// https://godbolt.org/z/GefKP5sj4
#include <iostream>
#include <thread>
#include <syncstream>
long fib(long n) { return n<=1 ? n : fib(n-1)+fib(n-2); }
void runFib(long from, long step, long to) {
for (auto n=from; n<=to; n+=step) {
std::osyncstream osync{ std::cout }; // Sync on cout as long as osync exists
osync << "fib("<<n<<")=" << fib(n) << '\n';
}
}
int main() {
std::jthread f40{ runFib, 1, 3, 40 };
std::jthread f41{ runFib, 2, 3, 41 };
std::jthread f42{ runFib, 3, 3, 42 };
}
Godbolt Listing lst-0032-godb.cpp, https://godbolt.org/z/GefKP5sj4:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/GefKP5sj4
#include <iostream>
#include <thread>
#include <syncstream>
long fib(long n) { return n<=1 ? n : fib(n-1)+fib(n-2); }
void runFib(long from, long step, long to) {
for (auto n=from; n<=to; n+=step) {
std::osyncstream osync{ std::cout }; // Sync on cout as long as osync exists
osync << "fib("<<n<<")=" << fib(n) << '\n';
}
}
int main() {
std::jthread f40{ runFib, 1, 3, 40 };
std::jthread f41{ runFib, 2, 3, 41 };
std::jthread f42{ runFib, 3, 3, 42 };
}
Listing 27.25: Writing to a “stringstream”.
Book listing lst-0033-book.cpp:
// https://godbolt.org/z/TT13E3sz5
#include <sstream> // ostringstream
#include <iostream>
int main() {
std::ostringstream ostr;
double dval = 3.1415;
int ival = 4321;
ostr << dval << " : " << ival;
const std::string sval = ostr.str();
std::cout << sval << std::endl; // Output: 3.1415 : 4321
}
Godbolt Listing lst-0033-godb.cpp, https://godbolt.org/z/TT13E3sz5:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/TT13E3sz5
#include <sstream> // ostringstream
#include <iostream>
int main() {
std::ostringstream ostr;
double dval = 3.1415;
int ival = 4321;
ostr << dval << " : " << ival;
const std::string sval = ostr.str();
std::cout << sval << std::endl; // Output: 3.1415 : 4321
}
Listing 27.26: Reading from a “stringstream”.
Book listing lst-0034-book.cpp:
// https://godbolt.org/z/1EMox3hW5
#include <sstream> // istringstream
#include <iostream>
int main() {
std::istringstream istr;
std::string sval("3.1415 : 4321");
std::string none;
double dval=0.0;
int ival=0;
istr.str(sval); // initialize
istr >> dval >> none >> ival; // read
if( ! istr.eof() ) {
std::cout << "Error converting\n"; return 1;
}
std::cout << dval << " == " << none << " == " << ival << "\n";
// Output: 3.1415 == : == 4321
}
Godbolt Listing lst-0034-godb.cpp, https://godbolt.org/z/1EMox3hW5:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/1EMox3hW5
#include <sstream> // istringstream
#include <iostream>
int main() {
std::istringstream istr;
std::string sval("3.1415 : 4321");
std::string none;
double dval=0.0;
int ival=0;
istr.str(sval); // initialize
istr >> dval >> none >> ival; // read
if( ! istr.eof() ) {
std::cout << "Error converting\n"; return 1;
}
std::cout << dval << " == " << none << " == " << ival << "\n";
// Output: 3.1415 == : == 4321
}
Listing 27.27: Type conversion using “stringstream”.
Book listing lst-0035-book.cpp:
// https://godbolt.org/z/vcoEcYYcx
#include <sstream> // stringstream
#include <iostream>
#include <stdexcept> // invalid_argument
template <class T1, class T2>
void myConvert(const T1& in, T2& out) {
std::stringstream ss;
ss << in;
ss >> out;
if( ! ss.eof() ) {
throw std::invalid_argument("Error during conversion");
}
}
int main() {
std::string sval;
float fval=3.1415f;
std::string sdval("5.321");
double dsval=0;
std::string doesnotwork("does not work");
try {
myConvert(fval, sval);
std::cout << sval << std::endl; // Output: 3.1415
myConvert(sdval, dsval);
std::cout << dsval << std::endl; // Output: 5.321
myConvert(doesnotwork, dsval); // triggers "Error during conversion"
}
catch(const std::invalid_argument& e) {
std::cout << e.what() << std::endl;
}
}
Godbolt Listing lst-0035-godb.cpp, https://godbolt.org/z/vcoEcYYcx:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/vcoEcYYcx
#include <sstream> // stringstream
#include <iostream>
#include <stdexcept> // invalid_argument
template <class T1, class T2>
void myConvert(const T1& in, T2& out) {
std::stringstream ss;
ss << in;
ss >> out;
if( ! ss.eof() ) {
throw std::invalid_argument("Error during conversion");
}
}
int main() {
std::string sval;
float fval=3.1415f;
std::string sdval("5.321");
double dsval=0;
std::string doesnotwork("does not work");
try {
myConvert(fval, sval);
std::cout << sval << std::endl; // Output: 3.1415
myConvert(sdval, dsval);
std::cout << dsval << std::endl; // Output: 5.321
myConvert(doesnotwork, dsval); // triggers "Error during conversion"
}
catch(const std::invalid_argument& e) {
std::cout << e.what() << std::endl;
}
}
Listing 27.28: The “to_string” function.
Book listing lst-0036-book.cpp:
// https://godbolt.org/z/z6sYqM48e
#include <iostream>
#include <string>
void show(double f) {
std::cout << "os: " << f
<< "\t to_string: " << std::to_string(f) << "\n";
}
int main() {
show(23.43); // Output: os: 23.43 to_string: 23.430000
show(1e-9); // Output: os: 1e-09 to_string: 0.000000
show(1e40); // Output: os: 1e+40 to_string: 100…0752.000000
show(1e-40); // Output: os: 1e-40 to_string: 0.000000
show(123456789); // Output: os: 1.23457e+08 to_string: 123456789.000000
}
Godbolt Listing lst-0036-godb.cpp, https://godbolt.org/z/z6sYqM48e:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/z6sYqM48e
#include <iostream>
#include <string>
void show(double f) {
std::cout << "os: " << f
<< "\t to_string: " << std::to_string(f) << "\n";
}
int main() {
show(23.43); // Output: os: 23.43 to_string: 23.430000
show(1e-9); // Output: os: 1e-09 to_string: 0.000000
show(1e40); // Output: os: 1e+40 to_string: 100…0752.000000
show(1e-40); // Output: os: 1e-40 to_string: 0.000000
show(123456789); // Output: os: 1.23457e+08 to_string: 123456789.000000
}
Listing 27.29: Transferring data from the “rdbuf”.
Book listing lst-0039-book.cpp:
// https://godbolt.org/z/8hK9Y4vhd
#include <fstream>
#include <iostream>
#include <memory> // unique_ptr
int main() {
std::fstream file("27Streams.tex"); // Open file for reading
auto bufptr = file.rdbuf(); // std::streambuf*
auto size = bufptr->pubseekoff(0, file.end); // std::streamsize
bufptr->pubseekoff(0, file.beg); // back to the beginning
auto buffer = std::unique_ptr<char[]>(new char[size]); // allocate memory
auto n = bufptr->sgetn(buffer.get(), size); // transfer number of chars
std::cout << "Characters read: " << n << "\n";
std::cout.write(buffer.get(), size); // Output char[]
}
Godbolt Listing lst-0039-godb.cpp, https://godbolt.org/z/8hK9Y4vhd:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/8hK9Y4vhd
#include <fstream>
#include <iostream>
#include <memory> // unique_ptr
int main() {
std::fstream file("27Streams.tex"); // Open file for reading
auto bufptr = file.rdbuf(); // std::streambuf*
auto size = bufptr->pubseekoff(0, file.end); // std::streamsize
bufptr->pubseekoff(0, file.beg); // back to the beginning
auto buffer = std::unique_ptr<char[]>(new char[size]); // allocate memory
auto n = bufptr->sgetn(buffer.get(), size); // transfer number of chars
std::cout << "Characters read: " << n << "\n";
std::cout.write(buffer.get(), size); // Output char[]
}
Listing 27.30: How to concatenate paths.
Book listing lst-0041-book.cpp:
// https://godbolt.org/z/jddKxj7fW
#include <filesystem> // std::filesystem
#include <iostream>
namespace fs = std::filesystem; using std::cout; using std::endl;
int main() {
// Path components
fs::path root {"/"};
fs::path dir {"var/www/"};
fs::path index {"index.html"};
// concatenate
fs::path p = root / dir / index; // operator/
// output
cout << "Name: " << p << endl; // "/var/www/index.html"
// decompose
cout << "Parent: " << p.parent_path() << endl; // "/var/www"
cout << "Name: " << p.filename() << endl; // "index.html"
cout << "Extension: " << p.extension() << endl; // ".html"
// Information
cout << std::boolalpha;
cout << "Exists? " << fs::exists(p) << endl;
cout << "Regular file? " << fs::is_regular_file(p) << endl;
}
Godbolt Listing lst-0041-godb.cpp, https://godbolt.org/z/jddKxj7fW:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/jddKxj7fW
#include <filesystem> // std::filesystem
#include <iostream>
namespace fs = std::filesystem; using std::cout; using std::endl;
int main() {
// Path components
fs::path root {"/"};
fs::path dir {"var/www/"};
fs::path index {"index.html"};
// concatenate
fs::path p = root / dir / index; // operator/
// output
cout << "Name: " << p << endl; // "/var/www/index.html"
// decompose
cout << "Parent: " << p.parent_path() << endl; // "/var/www"
cout << "Name: " << p.filename() << endl; // "index.html"
cout << "Extension: " << p.extension() << endl; // ".html"
// Information
cout << std::boolalpha;
cout << "Exists? " << fs::exists(p) << endl;
cout << "Regular file? " << fs::is_regular_file(p) << endl;
}
GodboltId:hTj94enjK
Book listing lst-0042-book.cpp:
// https://godbolt.org/z/hTj94enjK
#include <format>
#include <chrono>
#include <string>
#include <string_view>
#include <iostream>
using namespace std; using namespace std::literals;
void pr(string_view s) { cout << s << endl; }
double pi = 3.14159265359;
int main() {
pr(format("Hello, {}!", "Reader")); // simple C-string
pr(format("Hello, {}!", "Author"s)); // simple string
pr(format("You are {} years old.", 30)); // integers
pr(format("That makes {:.2f} euros.", 19.9933)); // 2 decimal places
pr(format("Scientific: {:e}", -44.876)); // results in "-4.487600e+01"
pr(format("Binary of {} is {:b}.", 42, 42)); // binary without base
pr(format("Hex of {} is {:#x}.", 73, 73)); // hexadecimal with base
pr(format("Zero-padded: {:03}", 7)); // results in "007"
pr(format("|{0:<10}|{1:^10}|{2:>10}|", "le", "mi", "ri"));
// Alignment and index
pr(format("{} {:.9}!", "Boa", "Constrictor")); // without index, truncate string
using namespace std::chrono; // neat time specifications:
pr(format("{}, {}", 2023y/11/5, minutes{20})); // Output: 2023-11-05, 20min
}
Godbolt Listing lst-0042-godb.cpp, https://godbolt.org/z/hTj94enjK:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/hTj94enjK
#include <format>
#include <chrono>
#include <string>
#include <string_view>
#include <iostream>
using namespace std; using namespace std::literals;
void pr(string_view s) { cout << s << endl; }
double pi = 3.14159265359;
int main() {
pr(format("Hello, {}!", "Reader")); // simple C-string
pr(format("Hello, {}!", "Author"s)); // simple string
pr(format("You are {} years old.", 30)); // integers
pr(format("That makes {:.2f} euros.", 19.9933)); // 2 decimal places
pr(format("Scientific: {:e}", -44.876)); // results in "-4.487600e+01"
pr(format("Binary of {} is {:b}.", 42, 42)); // binary without base
pr(format("Hex of {} is {:#x}.", 73, 73)); // hexadecimal with base
pr(format("Zero-padded: {:03}", 7)); // results in "007"
pr(format("|{0:<10}|{1:^10}|{2:>10}|", "le", "mi", "ri"));
// Alignment and index
pr(format("{} {:.9}!", "Boa", "Constrictor")); // without index, truncate string
using namespace std::chrono; // neat time specifications:
pr(format("{}, {}", 2023y/11/5, minutes{20})); // Output: 2023-11-05, 20min
}
Listing 27.31: A formatter can delegate parsing and formatting.
Book listing lst-0043-book.cpp:
// https://godbolt.org/z/sdWsnTonG
#include <format>
#include <string>
#include <vector>
#include <iostream>
struct Elf {
std::string name;
int birth_year;
std::string era;
std::string folk;
};
template<> struct std::formatter<Elf> {
std::formatter<std::string> sub_fmt;
constexpr auto parse(std::format_parse_context& pctx) {
return sub_fmt.parse(pctx); // returns iterator to '}'
}
auto format(const Elf& elf, std::format_context& fctx) const {
std::string s = std::format("{}/{} ({} {})",
elf.name, elf.folk, elf.birth_year, elf.era);
return sub_fmt.format(s, fctx); // delegate formatting
}
};
int main() {
std::vector<Elf> elves{
{"Feanor", 1169, "First Age", "Noldor"},
{"Galadriel", 1362, "EZ", "Noldor"},
{"Legolas", 87, "DZ", "Sindar"},
{"Elrond", 532, "EZ", "Half-elf"},
{"Elwe", 1050, "EZ", "Sindar"},
};
for (const auto& e : elves) {
std::cout << std::format("Elf: {:>20}", e) << std::endl;
}
}
Godbolt Listing lst-0043-godb.cpp, https://godbolt.org/z/sdWsnTonG:
//#(compile) c++; compiler:g141; options:-O1 -std=c++23; libs:-
// https://godbolt.org/z/sdWsnTonG
#include <format>
#include <string>
#include <vector>
#include <iostream>
struct Elf {
std::string name;
int birth_year;
std::string era;
std::string folk;
};
template<> struct std::formatter<Elf> {
std::formatter<std::string> sub_fmt;
constexpr auto parse(std::format_parse_context& pctx) {
return sub_fmt.parse(pctx); // returns iterator to '}'
}
auto format(const Elf& elf, std::format_context& fctx) const {
std::string s = std::format("{}/{} ({} {})",
elf.name, elf.folk, elf.birth_year, elf.era);
return sub_fmt.format(s, fctx); // delegate formatting
}
};
int main() {
std::vector<Elf> elves{
{"Feanor", 1169, "First Age", "Noldor"},
{"Galadriel", 1362, "EZ", "Noldor"},
{"Legolas", 87, "DZ", "Sindar"},
{"Elrond", 532, "EZ", "Half-elf"},
{"Elwe", 1050, "EZ", "Sindar"},
};
for (const auto& e : elves) {
std::cout << std::format("Elf: {:>20}", e) << std::endl;
}
}
Listing 27.32: A formatter can parse and output itself.
Book listing lst-0044-book.cpp:
// https://godbolt.org/z/WqjK31Gn6
// 'Elf' as before…
template<> struct std::formatter<Elf> {
std::string attribs; // Sequence of '%n', '%g', '%e', '%v', and others
constexpr auto parse(std::format_parse_context& pctx) {
auto it = std::ranges::find(pctx.begin(), pctx.end(), '}');// search for '}'
attribs = std::string(pctx.begin(), it); // save everything
return it; // points to '}'
}
auto format(const Elf& elf, std::format_context& fctx) const {
auto out = fctx.out(); // into here
for(auto n=0u; n<attribs.size()-1; ++n) {
if(attribs[n] == '%') { // instruction to output a member
switch(attribs[++n]) {
case 'n': out = std::format_to(out, "{}", elf.name); break;
case 'g': out = std::format_to(out, "{}", elf.birth_year); break;
case 'e': out = std::format_to(out, "{}", elf.era); break;
case 'v': out = std::format_to(out, "{}", elf.folk); break;
case '%': out = std::format_to(out, "%"); break; // %% becomes %
}
} else {
out = std::format_to(out, "{}", attribs[n]); // everything else
}
}
return out; // points to the end
}
};
int main() {
Elf e{"Feanor", 1169, "EZ", "Nordor"};
std::cout << std::format("{:Elf %n}", e) << std::endl;
// Output: Elf Feanor
std::cout << std::format("Elf {:%n, %v, born %g in the age %e}\n", e);
// Output: Elf Feanor, Nordor, born 1169 in the age EZ
}
Godbolt Listing lst-0044-godb.cpp, https://godbolt.org/z/WqjK31Gn6:
//#(compile) c++; compiler:g132; options:-O3 -std=c++23; libs:-
// https://godbolt.org/z/WqjK31Gn6
// 'Elf' as before…
template<> struct std::formatter<Elf> {
std::string attribs; // Sequence of '%n', '%g', '%e', '%v', and others
constexpr auto parse(std::format_parse_context& pctx) {
auto it = std::ranges::find(pctx.begin(), pctx.end(), '}');// search for '}'
attribs = std::string(pctx.begin(), it); // save everything
return it; // points to '}'
}
auto format(const Elf& elf, std::format_context& fctx) const {
auto out = fctx.out(); // into here
for(auto n=0u; n<attribs.size()-1; ++n) {
if(attribs[n] == '%') { // instruction to output a member
switch(attribs[++n]) {
case 'n': out = std::format_to(out, "{}", elf.name); break;
case 'g': out = std::format_to(out, "{}", elf.birth_year); break;
case 'e': out = std::format_to(out, "{}", elf.era); break;
case 'v': out = std::format_to(out, "{}", elf.folk); break;
case '%': out = std::format_to(out, "%"); break; // %% becomes %
}
} else {
out = std::format_to(out, "{}", attribs[n]); // everything else
}
}
return out; // points to the end
}
};
int main() {
Elf e{"Feanor", 1169, "EZ", "Nordor"};
std::cout << std::format("{:Elf %n}", e) << std::endl;
// Output: Elf Feanor
std::cout << std::format("Elf {:%n, %v, born %g in the age %e}\n", e);
// Output: Elf Feanor, Nordor, born 1169 in the age EZ
}