STL初探

本文作者初次尝试STL,从std::string开始。介绍了basic_string::replace函数参数含义,实现了给输入字符串两侧加双引号、处理原串中双引号的功能,还编写函数将原始串中所有替换源串替换成替换目的串,对比了Java相关类方法,为后续编程带来便利。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STL初探

 

以前总是听说STLStandard 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_typeiteratorEconst_iterator都是些什么啊?这可验证了这一句话:它的组件是高度参数化的

 

MSDN!得知:

size_type    表示长度的无符号整形数,当成unsigned int就行了;

iterator        枚举子,相当于集合中元素的位置的特殊表示;

E                     集合中元素的类型;

const_iterator 常量的iterator

 

再来看参数的具体含义(用参数名代替声明):

1p0, n0, s       p0开始的n0个(至多)字符被替换成s

2p0, n0, s, n  p0开始的n0个(至多)字符被替换成s的前n个字符(如果n>s.length(),那么将直接返回s);

3p0, n0, str   p0开始的n0个(至多)字符被替换成str

4p0, n0, str, pos, n   p0开始的n0个(至多)字符被替换成str的从pos开始的n个(至多)字符;

5p0, n0, n, c  p0开始的n0个(至多)字符被替换成由nc组成的串;

6~9 省略:          分别同1235

10first0, last0, first, last:从first0last0(不包括)的字符被替换成从firstlast(不包括)的字符(可能从来自另一串,否则结果总是为空串了)。

 

上面这些参数的含义都是我根据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实现了与VBReplace函数类似的字符串替换操作,给后续的编程带来了方便。与时同时,小试了STL一把,希望达到抛砖引玉的目的。而且,自己探索的过程是如此的美妙!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值