也可以这样编写 StrBlobPtr 的 deref 成员:
std::string& deref() const {
return (*check(curr, "dereference past end"))[curr];
}
你认为哪个版本更好?为什么?
原来的版本更好,可读性更高。
为了能让 StrBlobPtr 使用 const StrBlob,你觉得应该如何修改?定义一个名为ConstStrBlobPtr 的类,使其能够指向 const StrBlob。
构造函数改为接受 const Strblob &
, 然后给 Strblob 类添加两个 const 成员函数 cbegin 和 cend,返回 ConstStrBlobPtr。
编写一个程序,连接两个字符串字面常量,将结果保存在一个动态分配的char数组中。重写这个程序,连接两个标准库string对象。
#include
#include
#include
#include
int main() {
const char *c1 = "Hello ";
const char *c2 = "World";
unsigned len = strlen(c1) + strlen(c2) + 1;
char *r = new char[len]();
strcat_s(r, len, c1);
strcat_s(r, len, c2);
std::cout << r << std::endl;
std::string s1 = "Hello ";
std::string s2 = "World";
strcpy_s(r, len, (s1 + s2).c_str());
std::cout << r << std::endl;
delete[] r;
return 0;
}
编写一个程序,从标准输入读取一个字符串,存入一个动态分配的字符数组中。描述你的程序如何处理变长输入。测试你的程序,输入一个超出你分配的数组长度的字符串。
#include
int main()
{
std::cout << "How long do you want the string? ";
int size{ 0 };
std::cin >> size;
char *input = new char[size + 1]();
std::cin.ignore();
std::cout << "input the string: ";
std::cin.get(input, size + 1);
std::cout << input;
delete[] input;
return 0;
}
给定下面的new表达式,你应该如何释放pa?
int *pa = new int[10];
delete [] pa;
用 allocator 重写第427页中的程序。
#include
#include
#include
using namespace std;
int main()
{
int n = 5;
allocator alloc;
auto p = alloc.allocate(n);
string s;
auto q = p;
while (cin >> s && q != p + n)
{
alloc.construct(q++, s);
}
while (q != p)
{
std::cout << *--q << " ";
alloc.destroy(q);
}
alloc.deallocate(p, n);
return 0;
}
TextQuery 和 QueryResult 类只使用了我们已经介绍过的语言和标准库特性。不要提前看后续章节内容,只用已经学到的知识对这两个类编写你自己的版本。
#ifndef EX12_27_H
#define EX12_27_H
#include
#include
#include
#include
#include
#include "exercise12_27.h"
#include
#include
#include
#include
using namespace std;
TextQuery::TextQuery(ifstream& ifs) : file(new vector)
{
string text;
while (getline(ifs, text))
{
file->push_back(text);
int n = file->size() - 1;
istringstream line(text);
string word;
while (line >> word)
{
auto &lines = wm[word];
if (!lines)
lines.reset(new set);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const string& s) const
{
static shared_ptr> nodata(new set);
auto loc = wm.find(s);
if (loc == wm.end())
return QueryResult(s, nodata, file);
else
return QueryResult(s, loc->second, file);
}
std::ostream& print(std::ostream& os, const QueryResult& qr)
{
os << qr.sought << " occurs " << qr.lines->size() << " "
<< "time" << (qr.lines->size() > 1 ? "s" : "") << endl;
for (auto num : *qr.lines)
os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << endl;
return os;
}
#include
#include
#include
#include "exercise12_27.h"
using namespace std;
void runQueries(ifstream& infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to look for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q") break;
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream ifs("./data/storyDataFile.txt");
runQueries(ifs);
return 0;
}
编写程序实现文本查询,不要定义类来管理数据。你的程序应该接受一个文件,并与用户交互来查询单词。使用vector、map 和 set 容器来保存来自文件的数据并生成查询结果。
#include
using std::string;
#include
using std::vector;
#include
using std::shared_ptr;
#include
#include
#include
#include
我们曾经用do while 循环来编写管理用户交互的循环。用do while 重写本节程序,解释你倾向于哪个版本,为什么?
do {
std::cout << "enter word to look for, or q to quit: ";
string s;
if (!(std::cin >> s) || s == "q") break;
print(std::cout, tq.query(s)) << std::endl;
} while ( true );
我更喜欢 while,这可能是习惯的问题。
定义你自己版本的 TextQuery 和 QueryResult 类,并执行12.3.1节中的runQueries 函数。
#ifndef EX12_27_H
#define EX12_27_H
#include
#include
#include
#include
#include
#include "exercise12_27.h"
#include
#include
#include
#include
using namespace std;
TextQuery::TextQuery(ifstream& ifs) : file(new vector)
{
string text;
while (getline(ifs, text))
{
file->push_back(text);
int n = file->size() - 1;
istringstream line(text);
string word;
while (line >> word)
{
auto &lines = wm[word];
if (!lines)
lines.reset(new set);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const string& s) const
{
static shared_ptr> nodata(new set);
auto loc = wm.find(s);
if (loc == wm.end())
return QueryResult(s, nodata, file);
else
return QueryResult(s, loc->second, file);
}
std::ostream& print(std::ostream& os, const QueryResult& qr)
{
os << qr.sought << " occurs " << qr.lines->size() << " "
<< "time" << (qr.lines->size() > 1 ? "s" : "") << endl;
for (auto num : *qr.lines)
os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << endl;
return os;
}
#include
#include
#include
#include "exercise12_27.h"
using namespace std;
void runQueries(ifstream& infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to look for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q") break;
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream ifs("./data/storyDataFile.txt");
runQueries(ifs);
return 0;
}