STL初探
以前总是听说STL(Standard Template Library,即标准模板库)的大名,也知道它是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/ISO C++标准中最新的也是极具革命性的一部分。不过一直没有一试,今天看C++书时有个例子用到了std:string,字符串类应该说是每一种语言中最常用、最有用、功能最强大的类了;索性从它开始吧。
首先说明我的要求:把输入的字符串的两侧加上双引号;如果原串本身含有双引号,则在其前加上转义符/(即转义符)。简单吧!但我花了一个小时才弄明白。不信?来看看吧。
首先,我找到了std::string的一个成员函数basic_string::replace,有10个重载成员,如下:
basic_string& replace(size_type p0, size_type n0,
const E *s);
basic_string& replace(size_type p0, size_type n0,
const E *s, size_type n);
basic_string& replace(size_type p0, size_type n0,
const basic_string& str);
basic_string& replace(size_type p0, size_type n0,
const basic_string& str, size_type pos, size_type n);
basic_string& replace(size_type p0, size_type n0,
size_type n, E c);
basic_string& replace(iterator first0, iterator last0,
const E *s);
basic_string& replace(iterator first0, iterator last0,
const E *s, size_type n);
basic_string& replace(iterator first0, iterator last0,
const basic_string& str);
basic_string& replace(iterator first0, iterator last0,
size_type n, E c);
basic_string& replace(iterator first0, iterator last0,
const_iterator first, const_iterator last);
你看得懂吗?反正我是头都大了。size_type、iterator、E、const_iterator都是些什么啊?这可验证了这一句话:它的组件是高度参数化的。
查MSDN!得知:
size_type: 表示长度的无符号整形数,当成unsigned int就行了;
iterator: 枚举子,相当于集合中元素的位置的特殊表示;
E: 集合中元素的类型;
const_iterator: 常量的iterator。
再来看参数的具体含义(用参数名代替声明):
1、p0, n0, s: 从p0开始的n0个(至多)字符被替换成s;
2、p0, n0, s, n: 从p0开始的n0个(至多)字符被替换成s的前n个字符(如果n>s.length(),那么将直接返回s);
3、p0, n0, str: 从p0开始的n0个(至多)字符被替换成str;
4、p0, n0, str, pos, n: 从p0开始的n0个(至多)字符被替换成str的从pos开始的n个(至多)字符;
5、p0, n0, n, c: 从p0开始的n0个(至多)字符被替换成由n个c组成的串;
6~9 省略: 分别同1、2、3、5;
10?、first0, last0, first, last:从first0至last0(不包括)的字符被替换成从first至last(不包括)的字符(可能从来自另一串,否则结果总是为空串了)。
上面这些参数的含义都是我根据operand sequence(操作数次序)总结出来的。当然可能有谬误(特别是最后一个,我也不太确定)。原文如下:
Many member functions require an operand sequence of elements of type E. You can specify such an operand sequence several ways:
- c -- a sequence of one element with value c
- n, c -- a repetition of n elements each with value c
- s -- a null-terminated sequence (such as a C string, for E of type char) beginning at s (which must not be a null pointer), where the terminating element is the value E(0) and is not part of the operand sequence
- s, n -- a sequence of n elements beginning at s (which must not be a null pointer)
- str -- the sequence specified by the basic_string object str
- str, pos, n -- the substring of the basic_string object str with up to n elements (or through the end of the string, whichever comes first) beginning at position pos
- first, last -- a sequence of elements delimited by the iterators first and last, in the range [first, last)
这样一来,要实现上面所要求的功能(这段代码根本没有用到replace函数,我后来发现的,不过不用急,再下一个例子用得到的,~~~),自然不难了。如下:
//////////////////////////////////////////////////////////////////////////
/*
* 功能: 把输入的字符串的两侧加上双引号;如果原串本身含有双引号,则在其
前加上转义符/。
* 例如:
input return
======= =======
abc "abc"
a"bc "a/"bc"
*/
//////////////////////////////////////////////////////////////////////////
std::string quote(const std::string & input)
{
std::string strOut(input);
for(int i=0; i
{
if (strOut.at(i) == '"') // 判断第 i 个元素是不是 '"'?
{
strOut.insert(i, "//");
i++;
}
}
strOut = "/"" + strOut + "/"";
return strOut;
}
再后来,我发现这个函数缺一个很常用的功能:把串中的一个子串全部全部替换成另一个子串,就像是VB中的Replace一样。既然没有现成的,何不自己写一个函数来实现呢?如下:
//////////////////////////////////////////////////////////////////////////
/*
* 功能: 把 "原始串" 中所有的 "替换源串" 替换成 "替换目的串",返回替换完
的结果。
* 意义: 此功能解决了 std::string 中替换功能的单一,方便了编程。
*/
//////////////////////////////////////////////////////////////////////////
std::string stringReplace(const std::string& input, // 原始串
const std::string& find, // 替换源串
const std::string& replaceWith) // 替换目的串
{
std::string strOut(input);
int curPos = 0;
int pos;
while((pos = strOut.find(find, curPos)) != -1)
{
strOut.replace(pos, find.size(), replaceWith); // 一次替换
curPos = pos + replaceWith.size(); // 防止循环替换!!
}
return strOut;
}
其用法很简单,就不再详述。
我想:为什么STL中的没有直接把字符串替换成字符串的操作呢?查看Java Doc,得知:String类中只有java.lang.String.replace(char, char),也就是说它也完成不了上述功能(不过从v1.4开始,新加了另一个方法java.lang.String.replaceAll(java.lang.String, java.lang.String)可完成类似功能);再看StringBuffer类,只有一个java.lang.StringBuffer.replace(int, int, java.lang.String)方法,与上述重载3相似(说相似,自然还是不同,你看得出来吗?)。看来这是由来以久啊!
通过学习,使用std::string实现了与VB中Replace函数类似的字符串替换操作,给后续的编程带来了方便。与时同时,小试了STL一把,希望达到抛砖引玉的目的。而且,自己探索的过程是如此的美妙!