Parent directory entries-malformed.txt entries.txt io1.cpp io2.cpp io3.cpp template4.cpp to.cpp
Download
{ "Barack Obama" , 44 } {"Donald Duck",, 45} { "Joe Biden",46 }
{ "Barack Obama" , 44 } {"Donald Duck", 45} { "Joe Biden",46 }
#include <iostream> #include <iomanip> using namespace std; void print_io_states(ios& io) { cout << " fail()==" << io.fail(); cout << " bad()==" << io.bad(); cout << " eof()==" << io.eof(); } int sum_ints(istream& is) { int i, sum = 0; while (is >> i) { sum += i; cout << "current sum: " << setw(4) << sum; cout << '\t'; print_io_states(is); cout << '\n'; } return sum; } int main() { int sum = sum_ints(cin); cout << " final sum: " << setw(4) << sum; cout << '\t'; print_io_states(cin); cout << '\n'; }
#include <iostream> #include <iomanip> /* * You can detach C++ I/O streams from C standard I/O by doing this: * * std::ios_base::sync_with_stdio(false); * * When sync_with_stdio is set to true (default mode), C++ streams are * unbuffered, and each I/O operation on a C++ stream is immediately * applied to the corresponding C stream's buffer. When it is set to * false, the C++ streams are allowed to buffer their I/O independently, * which may be considerably faster in some cases. * * But note the following when it is set to false: * * - you can no longer mix C & C++ I/O * - C++ streams will no longer be thread-safe * - '\n' may not flush standard output connected to terminal */ using namespace std; void print_io_states(ios& io) { cout << " fail()==" << io.fail(); cout << " bad()==" << io.bad(); cout << " eof()==" << io.eof(); } int sum_ints(istream& is) { int i, sum = 0; while (!is.eof()) { is >> i; if (is.bad()) { throw runtime_error{"bad istream"}; } else if (is.fail()) { // fail(), but not bad() if (is.eof()) { // failbit && eofbit: this is normal (trailing whitespace) break; } // failbit && !eofbit: probably non-digit; just skip it is.clear(); char c; is.get(c); cout << " skipped: " << c << '\n'; } else { // read i successfully; // we could have hit eof or not (depends on trailing whitespace) sum += i; cout << "current sum: " << setw(4) << sum; cout << '\t'; print_io_states(is); cout << '\n'; } } return sum; } int main() { int sum = sum_ints(cin); cout << " final sum: " << setw(4) << sum; cout << '\t'; print_io_states(cin); cout << '\n'; }
#include <iostream> #include <iomanip> #include <fstream> using namespace std; struct Entry { string name; int number; }; ostream& operator<<(ostream& os, const Entry& e) { return os << "{\"" << e.name << "\", " << e.number << "}"; } /* * Read { "name" , number } pair from an istream. * * - code from "A Tour of C++", Sec 11.5 (3rd ed.) / Sec 10.5 (2nd ed.) */ istream& operator>>(istream& is, Entry& e) { char c, c2; if (is>>c && c=='{' && is>>c2 && c2=='"') { // start with a { " string name; while (is.get(c) && c!='"') // anything before " is part of name name+=c; if (is>>c && c==',') { int number = 0; if (is>>number>>c && c=='}') { // read the number and a } e = {name,number}; // assign to the entry return is; } } } is.setstate(ios_base::failbit); // register the failure in the stream return is; } int f1(istream& is); int f2(istream& is); int f3(const char *filename); int main(int argc, char **argv) { try { return f1(cin); //return f2(cin); //return f3(argv[1]); } catch (const exception& x) { cerr << x.what() << '\n'; } } int f1(istream& is) { Entry e; while (is >> e) { cout << e << '\n'; } // istream::operator bool() returns false if fail(), // which means failbit==1 or badbit==1 if (is.bad()) { throw runtime_error{"bad istream"}; } else if (!is.eof()) { throw invalid_argument{"bad entry format"}; } else { return 0; } } int f2(istream& is) { int r; string str; while (getline(is, str)) { istringstream iss(str); try { r = f1(iss); } catch (const invalid_argument& x) { cerr << x.what() << ": " << str << '\n'; } } return r; } int f3(const char *filename) { ifstream ifs { filename }; if (!ifs) { if (filename) throw runtime_error{"can't open file: "s + filename}; else throw runtime_error{"no file name"}; } return f2(ifs); }
#include <string> #include <vector> #include <iostream> template <typename T> class Vec { public: Vec() : sz{0}, cap{1}, a{new T[cap]} {} ~Vec() { delete[] a; } Vec(const Vec&) = delete; Vec& operator=(const Vec&) = delete; // Vec(const Vec&) = default; // Vec& operator=(const Vec&) = default; Vec(Vec&& ia) : sz{ia.sz}, cap{ia.cap}, a{ia.a} { ia.sz = ia.cap = 0; ia.a = nullptr; std::cout << "move ctor" << std::endl; } Vec& operator=(Vec&& ia) { if (this != &ia) { delete[] a; sz = ia.sz; cap = ia.cap; a = ia.a; ia.sz = ia.cap = 0; ia.a = nullptr; } std::cout << "move assignment" << std::endl; return *this; } T& operator[](int i) { return a[i]; } const T& operator[](int i) const { return a[i]; } int size() const { return sz; } int capacity() const { return cap; } void push_back(T x) { if (sz == cap) { // Separate cap*=2 to preserve invariant on exception // T *a2 = new T[cap *= 2]; T *a2 = new T[cap * 2]; cap *= 2; std::copy(a, a+sz, a2); delete[] a; a = a2; } a[sz++] = x; } private: size_t sz; size_t cap; T *a; }; template <typename T> std::ostream& operator<<(std::ostream& os, const Vec<T>& ia) { for (int i = 0; i < ia.size(); i++) { os << ia[i] << " "; } std::cout << "(cap=" << ia.capacity() << ")" << std::flush; return os; } using namespace std; Vec<int> createVecInt() { Vec<int> ia; for (int i = 0; i < 20; i++) { ia.push_back(i); cout << ia << endl; } return ia; } Vec<string> createVecStr() { Vec<string> ia; for (char c = 'A'; c <= 'Z'; c++) { string s; s += c; ia.push_back(s); cout << ia << endl; } return ia; } int main() { // Vec<int> ia { createVecInt() }; // Vec<string> ia2 { createVecStr() }; vector<string> v; for (char c = 'A'; c <= 'Z'; c++) { string s; s += c; v.push_back(s); for (const auto& e : v) { cout << e << " "; } cout << '\n'; } // Lecture plan: // // 1. IntArray code walk-through // // - ctor initializer syntax // - =delete & =default // - invariants // // 2. move ctor // // - rvalue reference // - -fno-elide-constructors // // 3. move assignment // // - casting to rvalue reference // // 4. IntArray to Vec<T> // // - Vec<int> // - Vec<string> // // 5. vector<string> // // - range for loop }
#include <iostream> #include <iomanip> #include <sstream> using namespace std; /* * Type-covert Source to Target * * - code from "A Tour of C++", Sec 11.7.3 (3rd ed.) / Sec 10.8 (2nd ed.) */ template <typename Target = string, typename Source = string> Target to(Source arg) { stringstream interpreter; Target result; if (!(interpreter << arg) || // write arg into stream !(interpreter >> result) || // read result from stream !(interpreter >> std::ws).eof()) // stuff left in stream? { throw runtime_error{"to<>() failed"}; } return result; } int main() { cout << to(40'000) << '\n'; cout << to<string,unsigned short>(80'000) << '\n'; }