C++ primer 第五版 中文版 练习 12.20
题目:编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印出StrBlob 中的每个元素。
答:
这个题需要用到上一个练习题的头文件,一并粘出来了
另外,这个用StrBlobPtr输出StrBlob内的元素值时,想了好久如何判断元素结尾,试了有大半小时。
最后用了 :对比StrBlobPtr对象当前元素值和 StrBlob的成员函数back()返回的元素值 的方法解决了这个问题。
以下是代码
首先是上一节的头文件和源文件:
mypractice_12_19.h
- /*
- 定义两个类 : StrBlobPtr、StrBlob
- */
- #ifndef mypractice
- #define mypractice
- #include <memory>
- #include <vector>
- #include <string>
- class StrBlob;
- class StrBlobPtr
- {
- public:
- friend class StrBlob;
- StrBlobPtr() :curr(0){}
- StrBlobPtr(StrBlob &a, size_t sz = 0); //这个一定要放在定义文件中去定义,不然会出现 “error C2027: 使用了未定义类型“StrBlob”错误和。
- std::string& deref() const; //返回curr位置上的元素值。
- StrBlobPtr& incr(); //功能类似于++curr,返回递增了迭代器的 StrBlobPtr对象。
- private:
- std::shared_ptr<std::vector<std::string>> check(std::size_t, const std::string&) const;
- std::weak_ptr<std::vector<std::string>> wptr;
- std::size_t curr;
- };
- class StrBlob
- {
- public:
- friend class StrBlobPtr;
- typedef std::vector<std::string>::size_type size_type;
- // 下面这个等同于上面这个。
- // using size_type = std::vector<std::string>::size_type;
- StrBlob();
- StrBlob(std::initializer_list<std::string> il);
- size_type size() const { return data->size(); }
- bool empty() const { return data->empty(); }
- //添加和删除元素
- void push_back(const std::string &t) { data->push_back(t); }
- void pop_back();
- //元素访问
- std::string& front();
- std::string& back();
- StrBlobPtr begin() { return StrBlobPtr(*this); }
- StrBlobPtr end()
- {
- auto ret = StrBlobPtr(*this, data->size());
- return ret;
- }
- private:
- std::shared_ptr<std::vector<std::string>> data;
- //如果data[i]不合法,抛出一个异常。
- void check(size_type i, const std::string &msg) const;
- };
- #endif
- #include "mypractice_12_19.h"
- using namespace std;
- //定义构造函数
- StrBlob::StrBlob() :data(make_shared<vector<string>>())
- {
- }
- StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il))
- {
- }
- void StrBlob::check(size_type i, const string &msg) const
- {
- if (i >= data->size())
- throw out_of_range(msg);
- }
- string& StrBlob::front()
- {
- check(0, "front on empty StrBlob");
- return data->front();
- }
- string& StrBlob::back()
- {
- check(0, "back on empty StrBlob");
- return data->back();
- }
- void StrBlob::pop_back()
- {
- check(0, "pop_back on empty StrBlob");
- data->pop_back();
- }
- StrBlobPtr::StrBlobPtr(StrBlob &a, size_t sz) :wptr(a.data), curr(sz)
- {
- }
- std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, const std::string &msg) const
- {
- auto ret = wptr.lock();
- if (!ret)
- throw std::out_of_range(msg);
- return ret;
- }
- std::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;
- }
包含main函数的源文件:mypractice_12_20.cpp
- /*
- 编写程序,逐行读入一个输入文件,将内容存入一个StrBlob中,用一个StrBlobPtr打印出StrBlob 中的每个元素。
- */
- #include "mypractice_12_19.h" //包含上一题的头文件。
- #include <fstream>
- #include <iostream>
- using namespace std;
- int main()
- {
- StrBlob mystrblob; //声明一个 StrBlob对象,默认初始化。
- StrBlobPtr mystrblobptr(mystrblob);//声明一个 StrBlobPtr对象并绑定到StrBlob,默认初始化。
- ifstream myifstream("1.txt");
- string line;
- //逐行读取文本内容,并按每行保存到 StrBlob 对象。
- while (getline(myifstream, line))
- {
- mystrblob.push_back(line);
- }
- //用StrBlobPtr输出StrBlob对象的内容。
- while (mystrblobptr.deref()!=mystrblob.back()) //这个判断比较诡异,我想出来后都感觉,太不可思议了,太不方便了。
- //都怪StrBlobPtr没有获取尾迭代器的成员函数。
- {
- cout << mystrblobptr.deref();
- mystrblobptr.incr();
- }
- return 0;
- }
- while many technological advances occur in an evolutionary manner,
- occasionally a revolutionary technological appears on the horizon that creates startling new conditions and profound changes.such is the case with the privat
- ely developed moller skycar,
- which is named after its inventor.with his permission,
- i would like to discuss the military potential of this vehicle.the ruggedized moller skycar variant the military is evaluating is called the light aerial
- multipurpose vehicle, or lamv (pronounced "lam-vee").
-
顶
- 0
-
踩