C++ Primer(第5版) 练习 12.20
练习 12.20 编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印出StrBlob中的每个元素。
环境:Linux Ubuntu(云服务器)
工具:vim
代码块
/*************************************************************************> File Name: ex12.20.cpp> Author: > Mail: > Created Time: Thu 18 Apr 2024 09:15:15 AM CST************************************************************************/#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<memory>
using namespace std;class StrBlobPtr;class StrBlob{friend class StrBlobPtr;public:typedef vector<string>::size_type size_type;StrBlob(): data(make_shared<vector<string>>()) {}StrBlob(initializer_list<string> il): data(make_shared<vector<string>>(il)) {}size_type size() const { return data->size(); }bool empty() const { return data->empty(); }void push_back(const string &t) { data->push_back(t); }void pop_back();string &front();string &back();string &front() const;string &back() const;StrBlobPtr begin();StrBlobPtr end();private:shared_ptr<vector<string>> data;void check(size_type i, const string &msg) const;
};void StrBlob::pop_back(){check(0, "pop_back on empty StrBlob");data->pop_back();
}string& StrBlob::front(){check(0, "front on empty StrBlob");return data->front();
}string& StrBlob::back(){check(0, "back on empty StrBlob");return data->back();
}string& StrBlob::front() const{check(0, "front on empty StrBlob");return data->front();
}string& StrBlob::back() const{check(0, "back on empty StrBlob");return data->back();
}void StrBlob::check(size_type i, const string &msg) const{if(i >= data->size()){throw out_of_range(msg);}
}class StrBlobPtr{friend bool compare(StrBlobPtr &a, const StrBlobPtr &b);public:StrBlobPtr(): curr(0) {}StrBlobPtr(StrBlob &s, size_t sz = 0): wptr(s.data), curr(sz) {}string &deref() const;StrBlobPtr &incr();private:shared_ptr<vector<string>> check(size_t, const string &) const;weak_ptr<vector<string>> wptr;size_t curr;
};shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const {auto ret = wptr.lock();if(!ret){throw runtime_error("unbound StrBlobPtr");}if(i >= ret->size()){throw out_of_range(msg);}return ret;
}string &StrBlobPtr::deref() const{auto p = check(curr, "dereference past end");return (*p)[curr];
}StrBlobPtr &StrBlobPtr::incr(){check(curr, "increment past end of StrBlobPtr");++curr;return *this;
}StrBlobPtr StrBlob::begin(){return StrBlobPtr(*this);
}StrBlobPtr StrBlob::end(){return StrBlobPtr(*this, data->size());
}bool compare(StrBlobPtr &a, const StrBlobPtr &b){if(a.wptr.lock() == b.wptr.lock() && a.curr == b.curr){return true;}return false;
}int main(){ifstream in("12.20.txt");StrBlob file;string str;StrBlobPtr nFile(file);while(getline(in, str)){file.push_back(str);}for(auto it = file.begin(); !compare(it, file.end()); it.incr()){cout<<it.deref()<<" ";}cout<<endl;in.close();return 0;
}