c++string一行中有数字_string c++ 把数字转成string - CSDN
  • c++中数字string转换

    2020-02-22 12:54:33
    网上流传的其他什么sstream,sprintf过于麻烦,提供便于记忆版本。 1.int->string ...string>...//从C++11开始引入 std::to_string(int) std::to_string(long) std::to_string(long long...

    网上流传的其他什么sstream,sprintf过于麻烦,提供便于记忆版本。

     

    1.int->string

     

    //头文件

    //#include<string>

    //注意这个是string,没有c

    //从C++11开始引入

     

    std::to_string(int)

    std::to_string(long)

    std::to_string(long long)

    std::to_string(float)

    std::to_string(double)

    std::to_string(long double)

    还支持各类unsigned,基本上主流数值类型都能无脑转换

     

    //转换时保留负号

    //参考https://blog.csdn.net/lzuacm/article/details/52704931

    //参考https://blog.csdn.net/u010510020/article/details/73799996

    //http://www.cplusplus.com/reference/string/to_string/

     

    2. string->int

     

    //头文件

    //#include<cstdlib>

    //标准库函数,但是使用时一般会配合<string>

     

    std::stoi

    std::stol

    std::stoll

    //看名字就知道对应为int,long,long long

     

    int stoi (const string&  str, size_t* idx = 0, int base = 10)
    
    //idx是一个指针,该指针指向一个size_t类型的对象
    //传入指针地址后,该对象的值会被修改为string中数值后的第一个字符所在位置
    //例如stoi("123abcd",&p),返回的p指向a所在
    //也可以把p的位置理解为数值部分的结束位置
    //int base是进制基数,默认10进制没什么好说的
    //需要注意的是stoi实质上是调用stol的

     

     

    //值得一提的是,在使用过程中发现,stoi会自动将string数值部分的首位0消去

    //同时还会保留负号,简直贴心,好评如潮

    //例如sto("00123abc"),结果为123,自动消去首位无效0

    //stoi("-0123"),结果为-123。 

     

    //参考http://www.cplusplus.com/reference/string/stoi/

    //参考http://www.cplusplus.com/reference/string/stol/

     

     

    3.截取替换查找

     

    下面的pos就是size_t类型的位置。

    记得上面stoi(string, &p )吗

    p是size_t类型的,其值会被修改数值后第一个字符所在位置(第一个字符为0)

    亦即数值部分的结束位置。

     

    例如:

    size_t p;

    stoi("123abc",&p);

    str2 = s.substr(p); // 从p位置开始,输出"abc"

     

    1. 截取子串
    
           s.substr(pos, n)    截取s中从pos开始(包括0)的n个字符的子串,并返回
    
           s.substr(pos)        截取s中从从pos开始(包括0)到末尾的所有字符的子串,并返回
    
    
    
    2. 替换子串
    
           s.replace(pos, n, s1)    用s1替换s中从pos开始(包括0)的n个字符的子串
    
    
    
    3. 查找子串
    
           s.find(s1)         查找s中第一次出现s1的位置,并返回(包括0)
    
           s.rfind(s1)        查找s中最后次出现s1的位置,并返回(包括0)
    
           s.find_first_of(s1)       查找在s1中任意一个字符在s中第一次出现的位置,并返回(包括0)
    
           s.find_last_of(s1)       查找在s1中任意一个字符在s中最后一次出现的位置,并返回(包括0)
    
           s.find_first_not_of(s1)         查找s中第一个不属于s1中的字符的位置,并返回(包括0)
    
           s.find_last_not_of(s1)         查找s中最后一个不属于s1中的字符的位置,并返回(包括0)



    //参考https://blog.csdn.net/ezhou_liukai/article/details/13779091

     

     

    4.string查找的一些说明

     

    c++定义的重载find()有4种:
    
    string (1)	
    size_t find (const string& str, size_t pos = 0) const;
    c-string (2)	
    size_t find (const char* s, size_t pos = 0) const;
    buffer (3)	
    size_t find (const char* s, size_t pos, size_t n) const;
    character (4)	
    size_t find (char c, size_t pos = 0) const;

     

    1.从str1的第p个位置开始查找str2

    2.对c中char*形式字符串数组的兼容形式,效果同1

    3.从str1的第pos个位置开始,查找str2的前n个字符,其中str2是char*类型

    4.对单个字符char c的兼容形式,效果同1

     

     

    特别的:

    //s.find()查找不到时,返回一个特别的静态常量,在c++中被定义为std::string::npos;

    //在vs2013中测试得到npos=4294967295,该值为unsigned int的理论最大值,转化为有符号即-1;

     

    5.string替换的重载

    //string (1)	
    string& replace (size_t pos,  size_t len,  const string& str);
    string& replace (iterator i1, iterator i2, const string& str);
    
    //substring (2)	
    string& replace (size_t pos,  size_t len,  const string& str,
                     size_t subpos, size_t sublen);
    
    //c-string (3)	
    string& replace (size_t pos,  size_t len,  const char* s);
    string& replace (iterator i1, iterator i2, const char* s);
    
    //buffer (4)	
    string& replace (size_t pos,  size_t len,  const char* s, size_t n);
    string& replace (iterator i1, iterator i2, const char* s, size_t n);
    
    //fill (5)	
    string& replace (size_t pos,  size_t len,  size_t n, char c);
    string& replace (iterator i1, iterator i2, size_t n, char c);
    
    //range (6)	
    template <class InputIterator>
      string& replace (iterator i1, iterator i2,
                       InputIterator first, InputIterator last);

     

    //fill(5),意思是从pos开始的len长度的子串,被替换为n个字符c。跟insert一样,当对象为char时,需要额外指定char的重复次数。 

     

    //参考http://www.cplusplus.com/reference/string/string/npos/

    //参考http://www.cplusplus.com/reference/string/string/find/

    //参考https://www.cnblogs.com/web100/archive/2012/12/02/cpp-string-find-npos.html

     

     

     

     

    4.string 转 char[]的说明

    不行开新文章了,直接更新在这。

     

    4.1 string内置s.c_str(),返回一个const char*指针

    string s="hello";

    const char* p = s.c_str();

    这是个临时指针,指向常量区某位置。修改s内容后,该指针不保证继续生效。

     

    4.2 string 转 char[]

     

    基本方法,逐位赋值。

    可以用上面的.c_str(),拿到指针p后,逐位访问。不过string类本身也支持逐位访问。

    这种方法显得比较蠢,而且还需要手动补结束符号。

    string s = "hello";
    char a[10];
    int i;
    for(i=0;i<s.size();++i){
        a[i] = s[i];
    }    
    p[i] = '\0';

     

    进阶方法,内置函数sscanf,一行语句搞定。

    注意,sscanf只能从const char* 中读取内容,所以需要用到上文说的.c_str()函数。

    string s="hello";
    char a[6];
    sscanf(s.c_str(), "%s", a);

    特别注意:char[]数组的长度需要预留一位给'\0',总是犯这个错误。

     

     

    5.string删除 - erase()

    隔一段时间不写oj,这些基础api又会忘记。

    不开新帖了,更在这里以后要刷题了就回来看看。

    basic_string & erase(size_type pos=0, size_type n=npos); / /从指定pos开始erase指定n个字符

    iterator erase(const_iterator position) //删除指定迭代器所指字符, 并返回下个字符的迭代器

    iterator erase(const_iterator first, const_iterator last) //删除[first, last)区间内所有字符

    后面两个用的少,主要是第一个erase(pos,n)。

     

    6.string插入insert

     

    string &insert(int p0, const char *s);——在p0位置插入字符串s

    string &insert(int p0, const char *s, int n);——在p0位置插入字符串s的前n个字符

    string &insert(int p0,const string &s);——在p0位置插入字符串s

    string &insert(int p0,const string &s, int pos, int n);——在p0位置插入字符串s从pos开始的连续n个字符

    string &insert(int p0, int n, char c);//在p0处插入n个字符c。先n后c。

    iterator insert(iterator it, char c);//在it处插入字符c,返回插入后迭代器的位置

    void insert(iterator it, const_iterator first, const_iteratorlast);//在it处插入从first开始至last-1的所有字符

    void insert(iterator it, int n, char c);//在it处插入n个字符c

     

    需求实例:

    我有一串"aabbb",想在末尾加入3个'c'。

    坑爹的是c里面字符串没有末尾插入的pushback这种东西。

    用insert还得先get length找到end所在position。

    这时候多么怀念python啊。。。。strt+3*'c'就能搞定了。 

    展开全文
  • c++ string头文件详解

    2018-12-09 21:42:45
    之所以抛弃char*的字符串而选用C++标准程序库string类,是因为他和前者比较起来,不必 担心内存是否足够、字符串长度等等,而且作为个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。...

    标准c++中string类函数介绍

    注意不是CString
    之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。

    好了,进入正题………
    首先,为了在我们的程序中使用string类型,我们必须包含头文件 <string>。

    如下:
    #include <string> //注意这里不是string.h string.h是C字符串头文件
    #include <string>
    using namespace std;

    1.声明一个C++字符串


    声明一个字符串变量很简单:
    string Str;
    这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str初始化为一个空字符串。String类的构造函数和析构函数如下:
    a)      string s;    //生成一个空字符串s
    b)      string s(str) //拷贝构造函数 生成str的复制品
    c)      string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值
    d)      string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值
    e)      string s(cstr) //将C字符串作为s的初值
    f)      string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。
    g)      string s(num,c) //生成一个字符串,包含num个c字符
    h)      string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值
    i)      s.~string() //销毁所有字符,释放内存
    都很简单,我就不解释了。

    2.字符串操作函数


    这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。
    a) =,assign()     //赋以新值
    b) swap()     //交换两个字符串的内容
    c) +=,append(),push_back() //在尾部添加字符
    d) insert() //插入字符
    e) erase() //删除字符
    f) clear() //删除全部字符
    g) replace() //替换字符
    h) + //串联字符串
    i) ==,!=,<,<=,>,>=,compare()    //比较字符串
    j) size(),length()    //返回字符数量
    k) max_size() //返回字符的可能最大个数
    l) empty()    //判断字符串是否为空
    m) capacity() //返回重新分配之前的字符容量
    n) reserve() //保留一定量内存以容纳一定数量的字符
    o) [ ], at() //存取单一字符
    p) >>,getline() //从stream读取某值
    q) <<    //将谋值写入stream
    r) copy() //将某值赋值为一个C_string
    s) c_str() //将内容以C_string返回
    t) data() //将内容以字符数组形式返回
    u) substr() //返回某个子字符串
    v)查找函数
    w)begin() end() //提供类似STL的迭代器支持
    x) rbegin() rend() //逆向迭代器
    y) get_allocator() //返回配置器

    下面详细介绍:

    2.1 C++字符串和C字符串的转换


    C ++提供的由C++字符串得到对应的C_string的方法是使用data()、c_str()和copy(),其中,data()以字符数组的形式返回字符串内容,但并不添加'/0'。c_str()返回一个以‘/0'结尾的字符数组,而copy()则把字符串的内容复制或写入既有的c_string或 字符数组内。C++字符串并不以'/0'结尾。我的建议是在程序中能使用C++字符串就使用,除非万不得已不选用c_string。由于只是简单介绍,详细介绍掠过,谁想进一步了解使用中的注意事项可以给我留言(到我的收件箱)。我详细解释。

    2.2 大小和容量函数


    一个C++字符串存在三种大小:a)现有的字符数,函数是size()和length(),他们等效。Empty()用来检查字符串是否为空。b)max_size() 这个大小是指当前C++字符串最多能包含的字符数,很可能和机器本身的限制或者字符串所在位置连续内存的大小有关系。我们一般情况下不用关心他,应该大小足够我们用的。但是不够用的话,会抛出length_error异常c)capacity()重新分配内存之前 string所能包含的最大字符数。这里另一个需要指出的是reserve()函数,这个函数为string重新分配内存。重新分配的大小由其参数决定, 默认参数为0,这时候会对string进行非强制性缩减。

    还有必要再重复一下C++字符串和C字符串转换的问 题,许多人会遇到这样的问题,自己做的程序要调用别人的函数、类什么的(比如数据库连接函数Connect(char*,char*)),但别人的函数参 数用的是char*形式的,而我们知道,c_str()、data()返回的字符数组由该字符串拥有,所以是一种const char*,要想作为上面提及的函数的参数,还必须拷贝到一个char*,而我们的原则是能不使用C字符串就不使用。那么,这时候我们的处理方式是:如果 此函数对参数(也就是char*)的内容不修改的话,我们可以这样Connect((char*)UserID.c_str(), (char*)PassWD.c_str()),但是这时候是存在危险的,因为这样转换后的字符串其实是可以修改的(有兴趣地可以自己试一试),所以我强调除非函数调用的时候不对参数进行修改,否则必须拷贝到一个char*上去。当然,更稳妥的办法是无论什么情况都拷贝到一个char*上去。同时我们也祈祷现在仍然使用C字符串进行编程的高手们(说他们是高手一点儿也不为过,也许在我们还穿开裆裤的时候他们就开始编程了,哈哈…)写的函数都比较规范,那样我们就不必进行强制转换了。

    2.3元素存取


    我们可以使用下标操作符[]和函数at()对元素包含的字符进行访问。但是应该注意的是操作符[]并不检查索引是否有效(有效索引0~str.length()),如果索引失效,会引起未定义的行为。而at()会检查,如果使用 at()的时候索引无效,会抛出out_of_range异常。

    有一个例外不得不说,const string a;的操作符[]对索引值是a.length()仍然有效,其返回值是'/0'。其他的各种情况,a.length()索引都是无效的。举例如下:
    const string Cstr(“const string”);
    string Str(“string”);
    Str[3];      //ok
    Str.at(3);    //ok
    Str[100]; //未定义的行为
    Str.at(100);    //throw out_of_range
    Str[Str.length()]    //未定义行为
    Cstr[Cstr.length()] //返回 ‘/0'
    Str.at(Str.length());//throw out_of_range
    Cstr.at(Cstr.length()) ////throw out_of_range
    我不赞成类似于下面的引用或指针赋值:
    char& r=s[2];
    char* p= &s[3];
    因为一旦发生重新分配,r,p立即失效。避免的方法就是不使用。

    2.4比较函数


    C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得 比较。字典排序靠前的字符小,比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小。同时,string (“aaaa”) <string(aaaaa)。

    另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。他返回一个整数来表示比较结果,返回值意义如下:0-相等 〉0-大于 <0-小于。举例如下:
    string s(“abcd”);
    s.compare(“abcd”); //返回0
    s.compare(“dcba”); //返回一个小于0的值
    s.compare(“ab”); //返回大于0的值
    s.compare(s); //相等
    s.compare(0,2,s,2,2); //用”ab”和”cd”进行比较 小于零
    s.compare(1,2,”bcx”,2); //用”bc”和”bc”比较。
    怎么样?功能够全的吧!什么?还不能满足你的胃口?好吧,那等着,后面有更个性化的比较算法。先给个提示,使用的是STL的比较算法。什么?对STL一窍不通?靠,你重修吧!

    2.5 更改内容


    这在字符串的操作中占了很大一部分。
    首先讲赋值,第一个赋值方法当然是使用操作符=,新值可以是string(如:s=ns) 、c_string(如:s=”gaint”)甚至单一字符(如:s='j')。还可以使用成员函数assign(),这个成员函数可以使你更灵活的对字符串赋值。还是举例说明吧:
    s.assign(str); //不说
    s.assign(str,1,3);//如果str是”iamangel” 就是把”ama”赋给字符串
    s.assign(str,2,string::npos);//把字符串str从索引值2开始到结尾赋给s
    s.assign(“gaint”); //不说
    s.assign(“nico”,5);//把'n' ‘I' ‘c' ‘o' ‘/0'赋给字符串
    s.assign(5,'x');//把五个x赋给字符串
    把字符串清空的方法有三个:s=””;s.clear();s.erase();(我越来越觉得举例比说话让别人容易懂!)。
    string提供了很多函数用于插入(insert)、删除(erase)、替换(replace)、增加字符。
    先说增加字符(这里说的增加是在尾巴上),函数有 +=、append()、push_back()。

    举例如下:
    s+=str;//加个字符串
    s+=”my name is jiayp”;//加个C字符串
    s+='a';//加个字符
    s.append(str);
    s.append(str,1,3);//不解释了 同前面的函数参数assign的解释
    s.append(str,2,string::npos)//不解释了
    s.append(“my name is jiayp”);
    s.append(“nico”,5);
    s.append(5,'x');
    s.push_back(‘a');//这个函数只能增加单个字符对STL熟悉的理解起来很简单

    也许你需要在string中间的某个位置插入字符串,这时候你可以用insert()函数,这个函数需要你指定一个安插位置的索引,被插入的字符串将放在这个索引的后面。
          s.insert(0,”my name”);
          s.insert(1,str);
    这种形式的insert()函数不支持传入单个字符,这时的单个字符必须写成字符串形式(让人恶心)。既然你觉得恶心,那就不得不继续读下面一段话:为了插 入单个字符,insert()函数提供了两个对插入单个字符操作的重载函数:insert(size_type index,size_type num,chart c)和insert(iterator pos,size_type num,chart c)。其中size_type是无符号整数,iterator是char*,所以,你这么调用insert函数是不行的:insert(0,1, 'j');这时候第一个参数将转换成哪一个呢?所以你必须这么写:insert((string::size_type)0,1,'j')!第二种形式指 出了使用迭代器安插字符的形式,在后面会提及。顺便提一下,string有很多操作是使用STL的迭代器的,他也尽量做得和STL靠近。

    删除函数erase()的形式也有好几种(真烦!),替换函数replace()也有好几个。

    举例吧:
    string s=”il8n”;
    s.replace(1,2,”nternationalizatio”);//从索引1开始的2个替换成后面的C_string
    s.erase(13);//从索引13开始往后全删除
    s.erase(7,5);//从索引7开始往后删5个

    2.6提取子串和字符串连接


    题取子串的函数是:substr(),形式如下:
    s.substr();//返回s的全部内容
    s.substr(11);//从索引11往后的子串
    s.substr(5,6);//从索引5开始6个字符
    把两个字符串结合起来的函数是+。(谁不明白请致电120)

    2.7输入输出操作


    1.>> 从输入流读取一个string。
    2.<< 把一个string写入输出流。
    另一个函数就是getline(),他从输入流读取一行内容,直到遇到分行符或到了文件尾。

    2.8搜索与查找


    查找函数很多,功能也很强大,包括了:
    find()
    rfind()
    find_first_of()
    find_last_of()
    find_first_not_of()
    find_last_not_of()

    这些函数返回符合搜索条件的字符区间内的第一个字符的索引,没找到目标就返回npos。所有的函数的参数说明如下:
    第一个参数是被搜寻的对象。第二个参数(可有可无)指出string内的搜寻起点索引,第三个参数(可有可无)指出搜寻的字符个数。比较简单,不多说不理解的可以向我提出,我再仔细的解答。当然,更加强大的STL搜寻在后面会有提及。

    最后再说说npos的含义,string::npos的类型是string::size_type,所以,一旦需要把一个索引与npos相比,这个索引值必须是string::size)type类型的,更多的情况下,我们可以直接把函数和npos进行比较(如:if(s.find(“jia”)== string::npos))。

    string类的构造函数:
    string(const char *s);    //用c字符串s初始化
    string(int n,char c);     //用n个字符c初始化
    此外,string类还支持默认构造函数和复制构造函数,如string s1;string s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常

    string类的字符操作:
    const char &operator[](int n)const;
    const char &at(int n)const;
    char &operator[](int n);
    char &at(int n);
    operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
    const char *data()const;//返回一个非null终止的c字符数组
    const char *c_str()const;//返回一个以null终止的c字符串
    int copy(char *s, int n, int pos = 0) const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目

    string的特性描述:
    int capacity()const;    //返回当前容量(即string中不必增加内存即可存放的元素个数)
    int max_size()const;    //返回string对象中可存放的最大字符串的长度
    int size()const;        //返回当前字符串的大小
    int length()const;       //返回当前字符串的长度
    bool empty()const;        //当前字符串是否为空
    void resize(int len,char c);//把字符串当前大小置为len,并用字符c填充不足的部分

    string类的输入输出操作:
    string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作。
    函数getline(istream &in,string &s);用于从输入流in中读取字符串到s中,以换行符'\n'分开。

    string的赋值:
    string &operator=(const string &s);//把字符串s赋给当前字符串
    string &assign(const char *s);//用c类型字符串s赋值
    string &assign(const char *s,int n);//用c字符串s开始的n个字符赋值
    string &assign(const string &s);//把字符串s赋给当前字符串
    string &assign(int n,char c);//用n个字符c赋值给当前字符串
    string &assign(const string &s,int start,int n);//把字符串s中从start开始的n个字符赋给当前字符串
    string &assign(const_iterator first,const_itertor last);//把first和last迭代器之间的部分赋给字符串

    string的连接:
    string &operator+=(const string &s);//把字符串s连接到当前字符串的结尾
    string &append(const char *s);            //把c类型字符串s连接到当前字符串结尾
    string &append(const char *s,int n);//把c类型字符串s的前n个字符连接到当前字符串结尾
    string &append(const string &s);    //同operator+=()
    string &append(const string &s,int pos,int n);//把字符串s中从pos开始的n个字符连接到当前字符串的结尾
    string &append(int n,char c);        //在当前字符串结尾添加n个字符c
    string &append(const_iterator first,const_iterator last);//把迭代器first和last之间的部分连接到当前字符串的结尾

    string的比较:
    bool operator==(const string &s1,const string &s2)const;//比较两个字符串是否相等
    运算符">","<",">=","<=","!="均被重载用于字符串的比较;
    int compare(const string &s) const;//比较当前字符串和s的大小
    int compare(int pos, int n,const string &s)const;//比较当前字符串从pos开始的n个字符组成的字符串与s的大小
    int compare(int pos, int n,const string &s,int pos2,int n2)const;//比较当前字符串从pos开始的n个字符组成的字符串与s中pos2开始的n2个字符组成的字符串的大小
    int compare(const char *s) const;
    int compare(int pos, int n,const char *s) const;
    int compare(int pos, int n,const char *s, int pos2) const;
    compare函数在>时返回1,<时返回-1,==时返回0   
    string的子串:
    string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串

    string的交换:
    void swap(string &s2);    //交换当前字符串与s2的值

    string类的查找函数:
    int find(char c, int pos = 0) const;//从pos开始查找字符c在当前字符串的位置
    int find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
    int find(const char *s, int pos, int n) const;//从pos开始查找字符串s中前n个字符在当前串中的位置
    int find(const string &s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
    //查找成功时返回所在位置,失败返回string::npos的值
    int rfind(char c, int pos = npos) const;//从pos开始从后向前查找字符c在当前串中的位置
    int rfind(const char *s, int pos = npos) const;
    int rfind(const char *s, int pos, int n = npos) const;
    int rfind(const string &s,int pos = npos) const;
    //从pos开始从后向前查找字符串s中前n个字符组成的字符串在当前串中的位置,成功返回所在位置,失败时返回string::npos的值
    int find_first_of(char c, int pos = 0) const;//从pos开始查找字符c第一次出现的位置
    int find_first_of(const char *s, int pos = 0) const;
    int find_first_of(const char *s, int pos, int n) const;
    int find_first_of(const string &s,int pos = 0) const;
    //从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。查找失败返回string::npos
    int find_first_not_of(char c, int pos = 0) const;
    int find_first_not_of(const char *s, int pos = 0) const;
    int find_first_not_of(const char *s, int pos,int n) const;
    int find_first_not_of(const string &s,int pos = 0) const;
    //从当前串中查找第一个不在串s中的字符出现的位置,失败返回string::npos
    int find_last_of(char c, int pos = npos) const;
    int find_last_of(const char *s, int pos = npos) const;
    int find_last_of(const char *s, int pos, int n = npos) const;
    int find_last_of(const string &s,int pos = npos) const;
    int find_last_not_of(char c, int pos = npos) const;
    int find_last_not_of(const char *s, int pos = npos) const;
    int find_last_not_of(const char *s, int pos, int n) const;
    int find_last_not_of(const string &s,int pos = npos) const;
    //find_last_of和find_last_not_of与find_first_of和find_first_not_of相似,只不过是从后向前查找

    string类的替换函数:
    string &replace(int p0, int n0,const char *s);//删除从p0开始的n0个字符,然后在p0处插入串s
    string &replace(int p0, int n0,const char *s, int n);//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符
    string &replace(int p0, int n0,const string &s);//删除从p0开始的n0个字符,然后在p0处插入串s
    string &replace(int p0, int n0,const string &s, int pos, int n);//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符
    string &replace(int p0, int n0,int n, char c);//删除p0开始的n0个字符,然后在p0处插入n个字符c
    string &replace(iterator first0, iterator last0,const char *s);//把[first0,last0)之间的部分替换为字符串s
    string &replace(iterator first0, iterator last0,const char *s, int n);//把[first0,last0)之间的部分替换为s的前n个字符
    string &replace(iterator first0, iterator last0,const string &s);//把[first0,last0)之间的部分替换为串s
    string &replace(iterator first0, iterator last0,int n, char c);//把[first0,last0)之间的部分替换为n个字符c
    string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);//把[first0,last0)之间的部分替换成[first,last)之间的字符串

    string类的插入函数:
    string &insert(int p0, const char *s);
    string &insert(int p0, const char *s, int n);
    string &insert(int p0,const string &s);
    string &insert(int p0,const string &s, int pos, int n);
    //前4个函数在p0位置插入字符串s中pos开始的前n个字符
    string &insert(int p0, int n, char c);//此函数在p0处插入n个字符c
    iterator insert(iterator it, char c);//在it处插入字符c,返回插入后迭代器的位置
    void insert(iterator it, const_iterator first, const_iterator last);//在it处插入[first,last)之间的字符
    void insert(iterator it, int n, char c);//在it处插入n个字符c

    string类的删除函数
    iterator erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置
    iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
    string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串

    string类的迭代器处理:
    string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。

    用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:
    const_iterator begin()const;
    iterator begin();                //返回string的起始位置
    const_iterator end()const;
    iterator end();                    //返回string的最后一个字符后面的位置
    const_iterator rbegin()const;
    iterator rbegin();                //返回string的最后一个字符的位置
    const_iterator rend()const;
    iterator rend();                    //返回string第一个字符位置的前面
    rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现

    字符串流处理:
    通过定义ostringstream和istringstream变量实现,<sstream>头文件中
    例如:
    string input("hello,this is a test");
    istringstream is(input);
    string s1,s2,s3,s4;
    is>>s1>>s2>>s3>>s4;//s1="hello,this",s2="is",s3="a",s4="test"
    ostringstream os;
    os<<s1<<s2<<s3<<s4;
    cout<<os.str();

    一直弄不清楚c++string变量中存储数字的原理,现在也是很模糊,先把知道的写上

    1如果往string变量中输入一个数字输出也是一个数字

    2如果往string变量中输入一个数字,但需要进行计算的时候需要-'0'

    3通过两个数字相加得到的第三个数字存入string中的时候,需要+'0'
     

    转载自:c++ string头文件

    展开全文
  • c++ string 用法详解

    2018-11-13 08:50:27
    c++ string 用法详解

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

    也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                   

     

    任何人对本文进行引用都要标明作者是Nicolai M.Josuttis

    ///////////////////////////////////////////////////////////////////////////////////

    C++ 语言是个十分优秀的语言,但优秀并不表示完美。还是有许多人不愿意使用C或者C++,为什么?原因众多,其中之一就是C/C++的文本处理功能太麻烦,用起来很不方便。以前没有接触过其他语言时,每当别人这么说,我总是不屑一顾,认为他们根本就没有领会C++的精华,或者不太懂C++,现在我接触 perl, php, 和Shell脚本以后,开始理解了以前为什么有人说C++文本处理不方便了。

     

    举例来说,如果文本格式是:用户名 电话号码,文件名name.txt
    Tom 23245332
    Jenny 22231231
    Heny 22183942
    Tom 23245332

    现在我们需要对用户名排序,且只输出不同的姓名。

    那么在shell 编程中,可以这样用:

    awk '{print $1}' name.txt | sort | uniq

    简单吧?

    如果使用C/C++ 就麻烦了,他需要做以下工作:
    先打开文件,检测文件是否打开,如果失败,则退出。
    声明一个足够大得二维字符数组或者一个字符指针数组
    读入一行到字符空间
    然后分析一行的结构,找到空格,存入字符数组中。
    关闭文件
    写一个排序函数,或者使用写一个比较函数,使用sort()排序
    遍历数组,比较是否有相同的,如果有,则要删除,copy…
    输出信息

    你可以用C++或者C语言去实现这个流程。如果一个人的主要工作就是处理这种类似的文本(例如做apache的日志统计和分析),你说他会喜欢C/C++么?

    当然,有了STL,这些处理会得到很大的简化。我们可以使用 fstream来代替麻烦的fopen fread fclose, 用vector来代替数组。最重要的是用 string来代替char * 数组,使用sort排序算法来排序,用unique 函数来去重。听起来好像很不错。看看下面代码(例程1):

    1. #include <string>  
    2. #include <iostream>  
    3. #include <algorithm>  
    4. #include <vector>  
    5. #include <fstream>  
    6. using namespace std;  
    7. int main()  
    8. {  
    9.     ifstream in("name.txt");  
    10.     string strtmp;  
    11.     vector<string> vect;  
    12.     while(getline(in, strtmp, '/n'))  
    13.     vect.push_back(strtmp.substr(0, strtmp.find(' ')));  
    14.     sort(vect.begin(), vect.end());  
    15.     vector<string>::iterator it=unique(vect.begin(), vect.end());  
    16.     copy(vect.begin(), it, ostream_iterator<string>(cout, "/n"));  
    17.     return 0;  
    18. }  
    #include <string>#include <iostream>#include <algorithm>#include <vector>#include <fstream>using namespace std;int main(){ ifstream in("name.txt"); string strtmp; vector<string> vect; while(getline(in, strtmp, '/n')) vect.push_back(strtmp.substr(0, strtmp.find(' '))); sort(vect.begin(), vect.end()); vector<string>::iterator it=unique(vect.begin(), vect.end()); copy(vect.begin(), it, ostream_iterator<string>(cout, "/n")); return 0;}
     

    也还不错吧,至少会比想象得要简单得多!(代码里面没有对错误进行处理,只是为了说明问题,不要效仿).

    当然,在这个文本格式中,不用vector而使用map会更有扩充性,例如,还可通过人名找电话号码等等,但是使用了map就不那么好用sort了。你可以用map试一试。

    这里string的作用不只是可以存储字符串,还可以提供字符串的比较,查找等。在sort和unique函数中就默认使用了less 和equal_to函数, 上面的一段代码,其实使用了string的以下功能:
    存储功能,在getline() 函数中
    查找功能,在find() 函数中
    子串功能,在substr() 函数中
    string operator < , 默认在sort() 函数中调用
    string operator == , 默认在unique() 函数中调用

    总之,有了string 后,C++的字符文本处理功能总算得到了一定补充,加上配合STL其他容器使用,其在文本处理上的功能已经与perl, shell, php的距离缩小很多了。 因此掌握string 会让你的工作事半功倍。

    1 string 使用

    其实,string并不是一个单独的容器,只是basic_string 模板类的一个typedef 而已,相对应的还有wstring, 你在string 头文件中你会发现下面的代码:

     extern "C++" {
    typedef basic_string <char> string;
    typedef basic_string <wchar_t> wstring;
    } // extern "C++" 

    由于只是解释string的用法,如果没有特殊的说明,本文并不区分string 和 basic_string的区别。

    string 其实相当于一个保存字符的序列容器,因此除了有字符串的一些常用操作以外,还有包含了所有的序列容器的操作。字符串的常用操作包括:增加、删除、修改、查找比较、链接、输入、输出等。详细函数列表参看附录。不要害怕这么多函数,其实有许多是序列容器带有的,平时不一定用的上。

    如果你要想了解所有函数的详细用法,你需要查看basic_string,或者下载STL编程手册。这里通过实例介绍一些常用函数。

    1.1 充分使用string 操作符

    string 重载了许多操作符,包括 +, +=, <, =, , [], <<, >>等,正式这些操作符,对字符串操作非常方便。先看看下面这个例子:

    1. #include <string>  
    2. #include <iostream>  
    3. using namespace std;  
    4. int main()  
    5. {  
    6.     string strinfo="Please input your name:";  
    7.     cout << strinfo ;  
    8.     cin >> strinfo;  
    9.     if( strinfo == "winter" )  
    10.         cout << "you are winter!"<<endl;  
    11.     else if( strinfo != "wende" )  
    12.         cout << "you are not wende!"<<endl;  
    13.     else if( strinfo < "winter")  
    14.         cout << "your name should be ahead of winter"<<endl;  
    15.     else  
    16.         cout << "your name should be after of winter"<<endl;  
    17.     strinfo += " , Welcome to China!";  
    18.     cout << strinfo<<endl;  
    19.     cout <<"Your name is :"<<strinfo<<endl;  
    20.     string strtmp = "How are you? " + strinfo;  
    21.     for(int i = 0 ; i < strtmp.size(); i ++)  
    22.         cout<<strtmp[i];  
    23.     return 0;  
    24. }  
    #include <string>#include <iostream>using namespace std;int main(){ string strinfo="Please input your name:"; cout << strinfo ; cin >> strinfo; if( strinfo == "winter" )  cout << "you are winter!"<<endl; else if( strinfo != "wende" )  cout << "you are not wende!"<<endl; else if( strinfo < "winter")  cout << "your name should be ahead of winter"<<endl; else  cout << "your name should be after of winter"<<endl; strinfo += " , Welcome to China!"; cout << strinfo<<endl; cout <<"Your name is :"<<strinfo<<endl; string strtmp = "How are you? " + strinfo; for(int i = 0 ; i < strtmp.size(); i ++)  cout<<strtmp[i]; return 0;}
     

    下面是程序的输出

     

    有了这些操作符,在STL中仿函数都可以直接使用string作为参数,例如 less, great, equal_to 等,因此在把string作为参数传递的时候,它的使用和int 或者float等已经没有什么区别了。例如,你可以使用:

    map<string, int> mymap; //以上默认使用了 less<string> 

    有了 operator + 以后,你可以直接连加,例如:

    string strinfo="Winter";
    string strlast="Hello " + strinfo + "!";
    string strtest="Hello " + strinfo + " Welcome" + " to China" + " !";//你还可以这样: 
     

    看见其中的特点了吗?只要你的等式里面有一个 string 对象,你就可以一直连续”+”,但有一点需要保证的是,在开始的两项中,必须有一项是 string 对象。其原理很简单:

    系统遇到”+”号,发现有一项是string 对象。
    系统把另一项转化为一个临时 string 对象。
    执行 operator + 操作,返回新的临时string 对象。
    如果又发现”+”号,继续第一步操作。

    由于这个等式是由左到右开始检测执行,如果开始两项都是const char* ,程序自己并没有定义两个const char* 的加法,编译的时候肯定就有问题了。

    有了操作符以后,assign(), append(), compare(), at()等函数,除非有一些特殊的需求时,一般是用不上。当然at()函数还有一个功能,那就是检查下标是否合法,如果是使用:

    string str="winter";//下面一行有可能会引起程序中断错误 str[100]='!';//下面会抛出异常:throws: out_of_range cout<<str.at(100)<<endl;

    了解了吗?如果你希望效率高,还是使用[]来访问,如果你希望稳定性好,最好使用at()来访问。

    1.2 眼花缭乱的string find 函数

    由于查找是使用最为频繁的功能之一,string 提供了非常丰富的查找函数。其列表如下:
    函数名 描述 find 查找 rfind 反向查找 find_first_of 查找包含子串中的任何字符,返回第一个位置 find_first_not_of 查找不包含子串中的任何字符,返回第一个位置 find_last_of 查找包含子串中的任何字符,返回最后一个位置 find_last_not_of 查找不包含子串中的任何字符,返回最后一个位置以上函数都是被重载了4次,以下是以find_first_of 函数为例说明他们的参数,其他函数和其参数一样,也就是说总共有24个函数 :

    size_type find_first_of(const basic_string& s, size_type pos = 0)

    size_type find_first_of(const charT* s, size_type pos, size_type n)

    size_type find_first_of(const charT* s, size_type pos = 0)

    size_type find_first_of(charT c, size_type pos = 0)

    所有的查找函数都返回一个size_type类型,这个返回值一般都是所找到字符串的位置,如果没有找到,则返回string::npos。有一点需要特别注意,所有和string::npos的比较一定要用string::size_type来使用,不要直接使用int 或者unsigned int等类型。其实string::npos表示的是-1, 看看头文件:

    template <class _CharT, class _Traits, class _Alloc>
    const basic_string<_CharT,_Traits,_Alloc>::size_type
    basic_string<_CharT,_Traits,_Alloc>::npos
    = basic_string<_CharT,_Traits,_Alloc>::size_type) -1;

    find 和 rfind 都还比较容易理解,一个是正向匹配,一个是逆向匹配,后面的参数pos都是用来指定起始查找位置。对于find_first_of 和find_last_of 就不是那么好理解。

    find_first_of 是给定一个要查找的字符集,找到这个字符集中任何一个字符所在字符串中第一个位置。或许看一个例子更容易明白。

    有这样一个需求:过滤一行开头和结尾的所有非英文字符。看看用string 如何实现:

    #include <string>
    #include <iostream>
    using namespace std;
    int main()
    {
     string strinfo=" //*---Hello Word!......------";
     string strset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     int first = strinfo.find_first_of(strset);
     if(first == string::npos)
     {
      cout<<"not find any characters"<<endl;
      return -1;
     }
     int last = strinfo.find_last_of(strset);
     if(last == string::npos)
     {
      cout<<"not find any characters"<<endl;
      return -1;
     }
     cout << strinfo.substr(first, last - first + 1)<<endl;
     return 0;
    }

    这里把所有的英文字母大小写作为了需要查找的字符集,先查找第一个英文字母的位置,然后查找最后一个英文字母的位置,然后用substr 来的到中间的一部分,用于输出结果。下面就是其结果:

    Hello Word

    前面的符号和后面的符号都没有了。像这种用法可以用来查找分隔符,从而把一个连续的字符串分割成为几部分,达到 shell 命令中的 awk 的用法。特别是当分隔符有多个的时候,可以一次指定。例如有这样的需求:

    张三|3456123, 湖南
    李四,4564234| 湖北
    王小二, 4433253|北京
    ...

    我们需要以 “|” “,”为分隔符,同时又要过滤空格,把每行分成相应的字段。可以作为你的一个作业来试试,要求代码简洁。

    1.3 string insert, replace, erase

    了解了string 的操作符,查找函数和substr,其实就已经了解了string的80%的操作了。insert函数, replace函数和erase函数在使用起来相对简单。下面以一个例子来说明其应用。
    string只是提供了按照位置和区间的replace函数,而不能用一个string字串来替换指定string中的另一个字串。这里写一个函数来实现这个功能:

    1. void string_replace(string & strBig, const string & strsrc, const string &strdst)  
    2. {  
    3.     string::size_type pos=0;  
    4.     string::size_type srclen=strsrc.size();  
    5.     string::size_type dstlen=strdst.size();  
    6.     while( (pos=strBig.find(strsrc, pos)) != string::npos)  
    7.     {  
    8.         strBig.replace(pos, srclen, strdst);  
    9.         pos += dstlen;  
    10.     }  
    11. }  
    void string_replace(string & strBig, const string & strsrc, const string &strdst){ string::size_type pos=0; string::size_type srclen=strsrc.size(); string::size_type dstlen=strdst.size(); while( (pos=strBig.find(strsrc, pos)) != string::npos) {  strBig.replace(pos, srclen, strdst);  pos += dstlen; }}

    看看如何调用:

    1. #include <string>  
    2. #include <iostream>  
    3. using namespace std;  
    4. int main()  
    5. {  
    6.     string strinfo="This is Winter, Winter is a programmer. Do you know Winter?";  
    7.     cout<<"Orign string is :/n"<<strinfo<<endl;  
    8.     string_replace(strinfo, "Winter""wende");  
    9.     cout<<"After replace Winter with wende, the string is :/n"<<strinfo<<endl;  
    10.     return 0;  
    11. }  
    #include <string>#include <iostream>using namespace std;int main(){ string strinfo="This is Winter, Winter is a programmer. Do you know Winter?"; cout<<"Orign string is :/n"<<strinfo<<endl; string_replace(strinfo, "Winter", "wende"); cout<<"After replace Winter with wende, the string is :/n"<<strinfo<<endl; return 0;}

    其输出结果:

    jieguo 
    如果不用replace函数,则可以使用erase和insert来替换,也能实现string_replace函数的功能:
    1. void string_replace(string & strBig, const string & strsrc, const string &strdst)  
    2. {  
    3.     string::size_type pos=0;  
    4.     string::size_type srclen=strsrc.size();  
    5.     string::size_type dstlen=strdst.size();  
    6.     while( (pos=strBig.find(strsrc, pos)) != string::npos)  
    7.     {  
    8.         strBig.erase(pos, srclen);  
    9.         strBig.insert(pos, strdst);  
    10.         pos += dstlen;  
    11.     }  
    12. }  
    void string_replace(string & strBig, const string & strsrc, const string &strdst){ string::size_type pos=0; string::size_type srclen=strsrc.size(); string::size_type dstlen=strdst.size(); while( (pos=strBig.find(strsrc, pos)) != string::npos) {  strBig.erase(pos, srclen);  strBig.insert(pos, strdst);  pos += dstlen; }}

    当然,这种方法没有使用replace来得直接。

    2 string 和C-style字符串

    现在看了这么多例子,发现const char* 可以和string 直接转换,例如我们在上面的例子中,使用

    string_replace(strinfo, "Winter", "wende");来代用void string_replace(string & strBig, const string & strsrc, const string &strdst)

    在C语言中只有char* 和 const char*,为了使用起来方便,string提供了三个函数满足其要求:

    const charT* c_str() const
    const charT* data() const
    size_type copy(charT* buf, size_type n, size_type pos = 0) const
    其中:
    c_str 直接返回一个以/0结尾的字符串。
    data 直接以数组方式返回string的内容,其大小为size()的返回值,结尾并没有/0字符。
    copy 把string的内容拷贝到buf空间中。
    你或许会问,c_str()的功能包含data(),那还需要data()函数干什么?看看源码:
    const charT* c_str () const
    {
     if (length () == 0)
      return "";
     terminate ();
     return data ();
    }
    原来c_str()的流程是:先调用terminate(),然后在返回data()。因此如果你对效率要求比较高,而且你的处理又不一定需要以/0的方式结束,你最好选择data()。但是对于一般的C函数中,需要以const char*为输入参数,你就要使用c_str()函数。

    对于c_str() data()函数,返回的数组都是由string本身拥有,千万不可修改其内容。其原因是许多string实现的时候采用了引用机制,也就是说,有可能几个string使用同一个字符存储空间。而且你不能使用sizeof(string)来查看其大小。详细的解释和实现查看Effective STL的条款15:小心string实现的多样性。

    另外在你的程序中,只在需要时才使用c_str()或者data()得到字符串,每调用一次,下次再使用就会失效,如:

    1. string strinfo("this is Winter");  
    2. ...  
    3. //最好的方式是:  
    4. foo(strinfo.c_str());  
    5. //也可以这么用:  
    6. const char* pstr=strinfo.c_str();  
    7. foo(pstr);  
    8. //不要再使用了pstr了, 下面的操作已经使pstr无效了。  
    9. strinfo += " Hello!";  
    10. foo(pstr);//错误!  
    string strinfo("this is Winter");...//最好的方式是:foo(strinfo.c_str());//也可以这么用:const char* pstr=strinfo.c_str();foo(pstr);//不要再使用了pstr了, 下面的操作已经使pstr无效了。strinfo += " Hello!";foo(pstr);//错误!

    会遇到什么错误?当你幸运的时候pstr可能只是指向”this is Winter Hello!”的字符串,如果不幸运,就会导致程序出现其他问题,总会有一些不可遇见的错误。总之不会是你预期的那个结果。

    3 string 和 Charactor Traits
    了解了string的用法,该详细看看string的真相了。前面提到string 只是basic_string的一个typedef。看看basic_string 的参数:

    template <class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
    class basic_string
    {
    //...
    }

    char_traits不仅是在basic_string 中有用,在basic_istream 和 basic_ostream中也需要用到。
    就像Steve Donovan在过度使用C++模板中提到的,这些确实有些过头了,要不是系统自己定义了相关的一些属性,而且用了个typedef,否则还真不知道如何使用。

    但复杂总有复杂道理。有了char_traits,你可以定义自己的字符串类型。当然,有了char_traits < char > 和char_traits < wchar_t > 你的需求使用已经足够了,为了更好的理解string ,咱们来看看char_traits都有哪些要求。

    如果你希望使用你自己定义的字符,你必须定义包含下列成员的结构: 表达式 描述

    char_type 字符类型
    int_type int 类型
    pos_type 位置类型
    off_type 表示位置之间距离的类型
    state_type 表示状态的类型
    assign(c1,c2) 把字符c2赋值给c1
    eq(c1,c2) 判断c1,c2 是否相等
    lt(c1,c2) 判断c1是否小于c2
    length(str) 判断str的长度
    compare(s1,s2,n) 比较s1和s2的前n个字符
    copy(s1,s2, n) 把s2的前n个字符拷贝到s1中
    move(s1,s2, n) 把s2中的前n个字符移动到s1中
    assign(s,n,c) 把s中的前n个字符赋值为c
    find(s,n,c) 在s的前n个字符内查找c
    eof() 返回end-of-file
    to_int_type(c) 将c转换成int_type
    to_char_type(i) 将i转换成char_type
    not_eof(i) 判断i是否为EOF
    eq_int_type(i1,i2) 判断i1和i2是否相等

    想看看实际的例子,你可以看看sgi STL的char_traits结构源码.

    现在默认的string版本中,并不支持忽略大小写的比较函数和查找函数,如果你想练练手,你可以试试改写一个char_traits , 然后生成一个case_string类, 也可以在string 上做继承,然后派生一个新的类,例如:ext_string,提供一些常用的功能,例如:

    定义分隔符。给定分隔符,把string分为几个字段。
    提供替换功能。例如,用winter, 替换字符串中的wende
    大小写处理。例如,忽略大小写比较,转换等
    整形转换。例如把”123″字符串转换为123数字。
    这些都是常用的功能,如果你有兴趣可以试试。其实有人已经实现了,看看Extended STL string。如果你想偷懒,下载一个头文件就可以用,有了它确实方便了很多。要是有人能提供一个支持正则表达式的string,我会非常乐意用。

    4 string 建议
    使用string 的方便性就不用再说了,这里要重点强调的是string的安全性。
    string并不是万能的,如果你在一个大工程中需要频繁处理字符串,而且有可能是多线程,那么你一定要慎重(当然,在多线程下你使用任何STL容器都要慎重)。
    string的实现和效率并不一定是你想象的那样,如果你对大量的字符串操作,而且特别关心其效率,那么你有两个选择,首先,你可以看看你使用的STL版本中string实现的源码;另一选择是你自己写一个只提供你需要的功能的类。
    string的c_str()函数是用来得到C语言风格的字符串,其返回的指针不能修改其空间。而且在下一次使用时重新调用获得新的指针。
    string的data()函数返回的字符串指针不会以’/0′结束,千万不可忽视。
    尽量去使用操作符,这样可以让程序更加易懂

    5 小结
    难怪有人说:string 使用方便功能强,我们一直用它!

    6 附录

    string 函数列表 函数名 描述
    begin 得到指向字符串开头的Iterator
    end 得到指向字符串结尾的Iterator
    rbegin 得到指向反向字符串开头的Iterator
    rend 得到指向反向字符串结尾的Iterator
    size 得到字符串的大小
    length 和size函数功能相同
    max_size 字符串可能的最大大小
    capacity 在不重新分配内存的情况下,字符串可能的大小
    empty 判断是否为空
    operator[] 取第几个元素,相当于数组
    c_str 取得C风格的const char* 字符串
    data 取得字符串内容地址
    operator= 赋值操作符
    reserve 预留空间
    swap 交换函数
    insert 插入字符
    append 追加字符
    push_back 追加字符
    operator+= += 操作符
    erase 删除字符串
    clear 清空字符容器中所有内容
    resize 重新分配空间
    assign 和赋值操作符一样
    replace 替代
    copy 字符串到空间
    find 查找
    rfind 反向查找
    find_first_of 查找包含子串中的任何字符,返回第一个位置
    find_first_not_of 查找不包含子串中的任何字符,返回第一个位置
    find_last_of 查找包含子串中的任何字符,返回最后一个位置
    find_last_not_of 查找不包含子串中的任何字符,返回最后一个位置
    substr 得到字串
    compare 比较字符串
    operator+ 字符串链接
    operator== 判断是否相等
    operator!= 判断是否不等于
    operator< 判断是否小于
    operator>> 从输入流中读入字符串
    operator<< 字符串写入输出流
    getline 从输入流中读入一行  

    ///////////////////////////////////////////////////////////////////////////////////

    之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。
    好了,进入正题………
    首先,为了在我们的程序中使用string类型,我们必须包含头文件 。如下:

    #include <string> //注意这里不是string.h string.h是C字符串头文件

    1.声明一个C++字符串
    声明一个字符串变量很简单:

    string Str;

    这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str初始化为一个空字符串。String类的构造函数和析构函数如下:

    1. a)    string s;  //生成一个空字符串s  
    2. b)    string s(str) //拷贝构造函数 生成str的复制品  
    3. c)    string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值  
    4. d)    string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值  
    5. e)    string s(cstr) //将C字符串作为s的初值  
    6. f)    string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。  
    7. g)    string s(num,c) //生成一个字符串,包含num个c字符  
    8. h)    string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值  
    9. i)    s.~string() //销毁所有字符,释放内存  
    a)    string s;  //生成一个空字符串sb)    string s(str) //拷贝构造函数 生成str的复制品c)    string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值d)    string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值e)    string s(cstr) //将C字符串作为s的初值f)    string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。g)    string s(num,c) //生成一个字符串,包含num个c字符h)    string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值i)    s.~string() //销毁所有字符,释放内存

    都很简单,我就不解释了。

    2.字符串操作函数
    这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。

    1. a) =,assign()   //赋以新值  
    2. b) swap()   //交换两个字符串的内容  
    3. c) +=,append(),push_back() //在尾部添加字符  
    4. d) insert() //插入字符  
    5. e) erase() //删除字符  
    6. f) clear() //删除全部字符  
    7. g) replace() //替换字符  
    8. h) + //串联字符串  
    9. i) ==,!=,<,<=,>,>=,compare()  //比较字符串  
    10. j) size(),length()  //返回字符数量  
    11. k) max_size() //返回字符的可能最大个数  
    12. l) empty()  //判断字符串是否为空  
    13. m) capacity() //返回重新分配之前的字符容量  
    14. n) reserve() //保留一定量内存以容纳一定数量的字符  
    15. o) [ ], at() //存取单一字符  
    16. p) >>,getline() //从stream读取某值  
    17. q) <<  //将谋值写入stream  
    18. r) copy() //将某值赋值为一个C_string  
    19. s) c_str() //将内容以C_string返回  
    20. t) data() //将内容以字符数组形式返回  
    21. u) substr() //返回某个子字符串  
    22. v)查找函数  
    23. w)begin() end() //提供类似STL的迭代器支持  
    24. x) rbegin() rend() //逆向迭代器  
    25. y) get_allocator() //返回配置器  
    a) =,assign()   //赋以新值b) swap()   //交换两个字符串的内容c) +=,append(),push_back() //在尾部添加字符d) insert() //插入字符e) erase() //删除字符f) clear() //删除全部字符g) replace() //替换字符h) + //串联字符串i) ==,!=,<,<=,>,>=,compare()  //比较字符串j) size(),length()  //返回字符数量k) max_size() //返回字符的可能最大个数l) empty()  //判断字符串是否为空m) capacity() //返回重新分配之前的字符容量n) reserve() //保留一定量内存以容纳一定数量的字符o) [ ], at() //存取单一字符p) >>,getline() //从stream读取某值q) <<  //将谋值写入streamr) copy() //将某值赋值为一个C_strings) c_str() //将内容以C_string返回t) data() //将内容以字符数组形式返回u) substr() //返回某个子字符串v)查找函数w)begin() end() //提供类似STL的迭代器支持x) rbegin() rend() //逆向迭代器y) get_allocator() //返回配置器

    下面详细介绍:

    2.1 C++字符串和C字符串的转换

    C++提供的由C++字符串得到对应的C_string的方法是使用data()、c_str()和copy(),其中,data()以字符数组的形式返回字符串内容,但并不添加’/0’。c_str()返回一个以‘/0’结尾的字符数组,而copy()则把字符串的内容复制或写入既有的c_string 或字符数组内。C++字符串并不以’/0’结尾。我的建议是在程序中能使用C++字符串就使用,除非万不得已不选用c_string。由于只是简单介绍,详细介绍掠过,谁想进一步了解使用中的注意事项可以给我留言(到我的收件箱)。我详细解释。

    2.2 大小和容量函数
    一个C++字符串存在三种大小:a)现有的字符数,函数是size()和length(),他们等效。Empty()用来检查字符串是否为空。 b)max_size() 这个大小是指当前C++字符串最多能包含的字符数,很可能和机器本身的限制或者字符串所在位置连续内存的大小有关系。我们一般情况下不用关心他,应该大小足够我们用的。但是不够用的话,会抛出length_error异常c)capacity()重新分配内存之前 string所能包含的最大字符数。这里另一个需要指出的是reserve()函数,这个函数为string重新分配内存。重新分配的大小由其参数决定,默认参数为0,这时候会对string进行非强制性缩减。

    还有必要再重复一下C++字符串和C字符串转换的问题,许多人会遇到这样的问题,自己做的程序要调用别人的函数、类什么的(比如数据库连接函数 Connect(char*,char*)),但别人的函数参数用的是char*形式的,而我们知道,c_str()、data()返回的字符数组由该字符串拥有,所以是一种const char*,要想作为上面提及的函数的参数,还必须拷贝到一个char*,而我们的原则是能不使用C字符串就不使用。那么,这时候我们的处理方式是:如果此函数对参数(也就是char*)的内容不修改的话,我们可以这样Connect((char*)UserID.c_str(), (char*)PassWD.c_str()),但是这时候是存在危险的,因为这样转换后的字符串其实是可以修改的(有兴趣地可以自己试一试),所以我强调除非函数调用的时候不对参数进行修改,否则必须拷贝到一个char*上去。当然,更稳妥的办法是无论什么情况都拷贝到一个char*上去。同时我们也祈祷现在仍然使用C字符串进行编程的高手们(说他们是高手一点儿也不为过,也许在我们还穿开裆裤的时候他们就开始编程了,哈哈…)写的函数都比较规范,那样我们就不必进行强制转换了。

    2.3元素存取
    我们可以使用下标操作符[]和函数at()对元素包含的字符进行访问。但是应该注意的是操作符[]并不检查索引是否有效(有效索引 0~str.length()),如果索引失效,会引起未定义的行为。而at()会检查,如果使用at()的时候索引无效,会抛出 out_of_range异常。
    有一个例外不得不说,const string a;的操作符[]对索引值是a.length()仍然有效,其返回值是’/0’。其他的各种情况,a.length()索引都是无效的。举例如下:

    const string Cstr(“const string”);
    string Str(“string”);

    Str[3];    //ok
    Str.at(3);  //ok

    Str[100]; //未定义的行为
    Str.at(100);  //throw out_of_range

    Str[Str.length()]  //未定义行为
    Cstr[Cstr.length()] //返回 ‘/0’
    Str.at(Str.length());//throw out_of_range
    Cstr.at(Cstr.length()) ////throw out_of_range

    我不赞成类似于下面的引用或指针赋值:
    char& r=s[2];
    char* p= &s[3];

    因为一旦发生重新分配,r,p立即失效。避免的方法就是不使用。

    2.4比较函数
    C++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得比较。字典排序靠前的字符小,比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小。同时,string(“aaaa”) 另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。他返回一个整数来表示比较结果,返回值意义如下:0-相等 〉0-大于 <0-小于。举例如下:

    1. string s(“abcd”);  
    2. s.compare(“abcd”); //返回0  
    3. s.compare(“dcba”); //返回一个小于0的值  
    4. s.compare(“ab”); //返回大于0的值  
    5. s.compare(s); //相等  
    6. s.compare(0,2,s,2,2); //用”ab”和”cd”进行比较 小于零  
    7. s.compare(1,2,”bcx”,2); //用”bc”和”bc”比较。  
    string s(“abcd”);s.compare(“abcd”); //返回0s.compare(“dcba”); //返回一个小于0的值s.compare(“ab”); //返回大于0的值s.compare(s); //相等s.compare(0,2,s,2,2); //用”ab”和”cd”进行比较 小于零s.compare(1,2,”bcx”,2); //用”bc”和”bc”比较。

    怎么样?功能够全的吧!什么?还不能满足你的胃口?好吧,那等着,后面有更个性化的比较算法。先给个提示,使用的是STL的比较算法。什么?对STL一窍不通?你重修吧!

    2.5 更改内容
    这在字符串的操作中占了很大一部分。
    首先讲赋值,第一个赋值方法当然是使用操作符=,新值可以是string(如:s=ns) 、c_string(如:s=”gaint”)甚至单一字符(如:s=’j’)。还可以使用成员函数assign(),这个成员函数可以使你更灵活的对字符串赋值。还是举例说明吧:

    s.assign(str); //直接
    s.assign(str,1,3);//如果str是”iamangel” 就是把”ama”赋给字符串
    s.assign(str,2,string::npos);//把字符串str从索引值2开始到结尾赋给s
    s.assign(“gaint”); //不说
    s.assign(“nico”,5);//把’n’ ‘I’ ‘c’ ‘o’ ‘/0’赋给字符串
    s.assign(5,’x’);//把五个x赋给字符串 
     

     

     

    把字符串清空的方法有三个:s=””;s.clear();s.erase();(我越来越觉得举例比说话让别人容易懂!)。
    string提供了很多函数用于插入(insert)、删除(erase)、替换(replace)、增加字符。
    先说增加字符(这里说的增加是在尾巴上),函数有 +=、append()、push_back()。举例如下:

    s+=str;//加个字符串 s+=”my name is jiayp”;//加个C字符串 s+=’a’;//加个字符 s.append(str); s.append(str,1,3);//不解释了 同前面的函数参数assign的解释 s.append(str,2,string::npos)//不解释了 s.append(“my name is jiayp”); s.append(“nico”,5); s.append(5,’x’); s.push_back(‘a’);//这个函数只能增加单个字符 对STL熟悉的理解起来很简单

    也许你需要在string中间的某个位置插入字符串,这时候你可以用insert()函数,这个函数需要你指定一个安插位置的索引,被插入的字符串将放在这个索引的后面。

     s.insert(0,”my name”); s.insert(1,str); 

    这种形式的insert()函数不支持传入单个字符,这时的单个字符必须写成字符串形式(让人恶心)。既然你觉得恶心,那就不得不继续读下面一段话:为了插入单个字符,insert()函数提供了两个对插入单个字符操作的重载函数:insert(size_type index,size_type num,chart c)和insert(iterator pos,size_type num,chart c)。其中size_type是无符号整数,iterator是char*,所以,你这么调用insert函数是不行的:insert(0,1,’j’);这时候第一个参数将转换成哪一个呢?所以你必须这么写:insert((string::size_type)0,1,’j’)!第二种形式指出了使用迭代器安插字符的形式,在后面会提及。顺便提一下,string有很多操作是使用STL的迭代器的,他也尽量做得和STL靠近。
    删除函数erase()的形式也有好几种(真烦!),替换函数replace()也有好几个。举例吧:

    string s=”il8n”; s.replace(1,2,”nternationalizatio”);//从索引1开始的2个替换成后面的C_string s.erase(13);//从索引13开始往后全删除 s.erase(7,5);//从索引7开始往后删5个

    2.6提取子串和字符串连接

    题取子串的函数是:substr(),形式如下:

    s.substr();//返回s的全部内容 s.substr(11);//从索引11往后的子串 s.substr(5,6);//从索引5开始6个字符

    把两个字符串结合起来的函数是+。(谁不明白请致电120)

    2.7输入输出操作
    1.>> 从输入流读取一个string。
    2.<< 把一个string写入输出流。
    另一个函数就是getline(),他从输入流读取一行内容,直到遇到分行符或到了文件尾。

    2.8搜索与查找
    查找函数很多,功能也很强大,包括了:

     find() rfind() find_first_of() find_last_of() find_first_not_of() find_last_not_of()  

    这些函数返回符合搜索条件的字符区间内的第一个字符的索引,没找到目标就返回npos。所有的函数的参数说明如下:
    第一个参数是被搜寻的对象。第二个参数(可有可无)指出string内的搜寻起点索引,第三个参数(可有可无)指出搜寻的字符个数。比较简单,不多说 不理解的可以向我提出,我再仔细的解答。当然,更加强大的STL搜寻在后面会有提及。
    最后再说说npos的含义,string::npos的类型是string::size_type,所以,一旦需要把一个索引与npos相比,这个索引值必须是string::size)type类型的,更多的情况下,我们可以直接把函数和npos进行比较(如:if(s.find(“jia”)==string::npos))。

     

    任何人对本文进行引用都要标明作者是Nicolai M.Josuttis 译者是侯捷/孟岩

               

    给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

    这里写图片描述
    展开全文
  • C++String中的find用法

    2019-05-30 13:45:06
    #include<string>...find是string中一个查找函数。 find用法: 1.find() 示例:(上代码) #include<iostream> #include<string> using namespace std; int main() { s...
    
    #include<string>

    string 是c++中一个非常重要函数。

    在处理字符串的时候经常用到。

    find是string中一个查找函数。

    find用法:

    1.find()

    示例:(上代码)

    #include<iostream>
    #include<string>
    using namespace std;
    int main()
    {
    	string a;
    	string b;
    	
    	getline(cin,a);
    	getline(cin,b);
    	
    	int post=b.find(a);
    	
    	cout<<post<<endl;
    	return 0;
    }

    首先定义两个string类型的变量a和b,getline()是string中的一个方法,从键盘读取一行。

    b.find(a);这句代码的意思就是从b字符串中查找a字符串。

    公式可以理解为————>母字符串.find(子字符串);

    返回值的类型为int类型,返回的是字符串的下标。

    #include<iostream>
    #include<string>
    using namespace std;
    int main()
    {
    
     	string st1("babbabab");
        cout << st1.find('a') << endl;//1   由原型知,若省略第2个参数,则默认从位置0(即第1个字符)起开始查找
        cout << st1.find('a', 0) << endl;//1
        cout << st1.find('a', 1) << endl;//1   
        cout << st1.find('a', 2) << endl;//4
    
        return 0;
    }

    st1.find('a',1);后面的数字代表从什么位置开始查找。如果不加,默认从位置0(即第一个字符)开始查找。

    如果你要查找的字符不是单个字母,用法和查找单个字母一样,它会返回第一个字符的位置。

     

    2.rfind()

    rfind()就是倒着查找。。。。

    后面的数字代表着就是从倒数第几个开始查找。

     

     

    在这里说一下,如果计算机没有找到,就会返回npos!!

     

    	if(b.find(a)==string::npos)
    	{
    		cout<<"no find"<<endl;
    	}

    比如说看这个代码,,如果返回值等于npos,就说明在b字符串里面,没有找到a。

     

    3.find_first_of()

            在源串中从位置pos起往后查找,只要在源串中遇到一个字符,该字符与目标串中任意一个字符相同,就停止查找,返回该字符在源串中的位置;若匹配失败,返回npos。

    示例

    //将字符串中所有的元音字母换成*
    //代码来自C++ Reference,地址:http://www.cplusplus.com/reference/string/basic_string/find_first_of/
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main()
    {
        std::string str("PLease, replace the vowels in this sentence by asterisks.");
        std::string::size_type found = str.find_first_of("aeiou");
        while (found != std::string::npos)
        {
            str[found] = '*';
            found = str.find_first_of("aeiou", found + 1);
        }
        std::cout << str << '\n';
        return 0;
    }
    //运行结果:
    //PL**s* r*pl*c* th* v*w*ls *n th*s s*nt*nc* by *st*r*sks

    4.find_last_of()

     

    函数与find_first_of()函数相似,只不过查找顺序是从指定位置向前。

     

    5.find_first_not_of()


          在源串中从位置pos开始往后查找,只要在源串遇到一个字符,该字符与目标串中的任意一个字符都不相同,就停止查找,返回该字符在源串中的位置;若遍历完整个源串,都找不到满  足条件的字符,则返回npos。

    示例

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main()
    {
        //测试size_type find_first_not_of (const charT* s, size_type pos = 0) const;
        string str("abcdefg");
        cout << str.find_first_not_of("kiajbvehfgmlc", 0) << endl;//3   从源串str的位置0(a)开始查找,目标串中有a(匹配),再找b,b匹配,再找c,c匹配,
                                                                  //    再找d,目标串中没有d(不匹配),停止查找,返回d在str中的位置3
        return 0;
    }

    可以复制下来,自己验证一下。

    6.find_last_not_of()

    find_last_not_of()与find_first_not_of()相似,只不过查找顺序是从指定位置向前。

     

     

                                                                                                                   借鉴:https://www.cnblogs.com/zpcdbky/p/4471454.html

     

     

    展开全文
  • c++ string头文件

    2016-10-13 18:25:36
    之所以抛弃char*的字符串而选用C++标准程序库string类,是因为他和前者比较起来,不必 担心内存是否足够、字符串长度等等,而且作为个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。...


    标准c++中string类函数介绍

    注意不是CString
    之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。

    好了,进入正题………
    首先,为了在我们的程序中使用string类型,我们必须包含头文件 <string>。

    如下:
    #include <string> //注意这里不是string.h string.h是C字符串头文件
    #include <string>
    using namespace std;

    1.声明一个C++字符串
    声明一个字符串变量很简单:
    string Str;
    这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str初始化为一个空字符串。String类的构造函数和析构函数如下:
    a)      string s;    //生成一个空字符串s
    b)      string s(str) //拷贝构造函数 生成str的复制品
    c)      string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值
    d)      string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值
    e)      string s(cstr) //将C字符串作为s的初值
    f)      string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。
    g)      string s(num,c) //生成一个字符串,包含num个c字符
    h)      string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值
    i)      s.~string() //销毁所有字符,释放内存
    都很简单,我就不解释了。

    2.字符串操作函数
    这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。
    a) =,assign()     //赋以新值
    b) swap()     //交换两个字符串的内容
    c) +=,append(),push_back() //在尾部添加字符
    d) insert() //插入字符
    e) erase() //删除字符
    f) clear() //删除全部字符
    g) replace() //替换字符
    h) + //串联字符串
    i) ==,!=,<,<=,>,>=,compare()    //比较字符串
    j) size(),length()    //返回字符数量
    k) max_size() //返回字符的可能最大个数
    l) empty()    //判断字符串是否为空
    m) capacity() //返回重新分配之前的字符容量
    n) reserve() //保留一定量内存以容纳一定数量的字符
    o) [ ], at() //存取单一字符
    p) >>,getline() //从stream读取某值
    q) <<    //将谋值写入stream
    r) copy() //将某值赋值为一个C_string
    s) c_str() //将内容以C_string返回
    t) data() //将内容以字符数组形式返回
    u) substr() //返回某个子字符串
    v)查找函数
    w)begin() end() //提供类似STL的迭代器支持
    x) rbegin() rend() //逆向迭代器
    y) get_allocator() //返回配置器

    下面详细介绍:

    2.1 C++字符串和C字符串的转换
    C ++提供的由C++字符串得到对应的C_string的方法是使用data()、c_str()和copy(),其中,data()以字符数组的形式返回字符串内容,但并不添加'/0'。c_str()返回一个以‘/0'结尾的字符数组,而copy()则把字符串的内容复制或写入既有的c_string或 字符数组内。C++字符串并不以'/0'结尾。我的建议是在程序中能使用C++字符串就使用,除非万不得已不选用c_string。由于只是简单介绍,详细介绍掠过,谁想进一步了解使用中的注意事项可以给我留言(到我的收件箱)。我详细解释。

    2.2 大小和容量函数
    一个C++字符串存在三种大小:a)现有的字符数,函数是size()和length(),他们等效。Empty()用来检查字符串是否为空。b)max_size() 这个大小是指当前C++字符串最多能包含的字符数,很可能和机器本身的限制或者字符串所在位置连续内存的大小有关系。我们一般情况下不用关心他,应该大小足够我们用的。但是不够用的话,会抛出length_error异常c)capacity()重新分配内存之前 string所能包含的最大字符数。这里另一个需要指出的是reserve()函数,这个函数为string重新分配内存。重新分配的大小由其参数决定, 默认参数为0,这时候会对string进行非强制性缩减。

    还有必要再重复一下C++字符串和C字符串转换的问 题,许多人会遇到这样的问题,自己做的程序要调用别人的函数、类什么的(比如数据库连接函数Connect(char*,char*)),但别人的函数参 数用的是char*形式的,而我们知道,c_str()、data()返回的字符数组由该字符串拥有,所以是一种const char*,要想作为上面提及的函数的参数,还必须拷贝到一个char*,而我们的原则是能不使用C字符串就不使用。那么,这时候我们的处理方式是:如果 此函数对参数(也就是char*)的内容不修改的话,我们可以这样Connect((char*)UserID.c_str(), (char*)PassWD.c_str()),但是这时候是存在危险的,因为这样转换后的字符串其实是可以修改的(有兴趣地可以自己试一试),所以我强调除非函数调用的时候不对参数进行修改,否则必须拷贝到一个char*上去。当然,更稳妥的办法是无论什么情况都拷贝到一个char*上去。同时我们也祈祷现在仍然使用C字符串进行编程的高手们(说他们是高手一点儿也不为过,也许在我们还穿开裆裤的时候他们就开始编程了,哈哈…)写的函数都比较规范,那样我们就不必进行强制转换了。

    2.3元素存取
    我们可以使用下标操作符[]和函数at()对元素包含的字符进行访问。但是应该注意的是操作符[]并不检查索引是否有效(有效索引0~str.length()),如果索引失效,会引起未定义的行为。而at()会检查,如果使用 at()的时候索引无效,会抛出out_of_range异常。

    有一个例外不得不说,const string a;的操作符[]对索引值是a.length()仍然有效,其返回值是'/0'。其他的各种情况,a.length()索引都是无效的。举例如下:
    const string Cstr(“const string”);
    string Str(“string”);
    Str[3];      //ok
    Str.at(3);    //ok
    Str[100]; //未定义的行为
    Str.at(100);    //throw out_of_range
    Str[Str.length()]    //未定义行为
    Cstr[Cstr.length()] //返回 ‘/0'
    Str.at(Str.length());//throw out_of_range
    Cstr.at(Cstr.length()) ////throw out_of_range
    我不赞成类似于下面的引用或指针赋值:
    char& r=s[2];
    char* p= &s[3];
    因为一旦发生重新分配,r,p立即失效。避免的方法就是不使用。

    2.4比较函数
    C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。在使用>,>=,<,<=这些操作符的时候是根据“当前字符特性”将字符按字典顺序进行逐一得 比较。字典排序靠前的字符小,比较的顺序是从前向后比较,遇到不相等的字符就按这个位置上的两个字符的比较结果确定两个字符串的大小。同时,string (“aaaa”) <string(aaaaa)。

    另一个功能强大的比较函数是成员函数compare()。他支持多参数处理,支持用索引值和长度定位子串来进行比较。他返回一个整数来表示比较结果,返回值意义如下:0-相等 〉0-大于 <0-小于。举例如下:
    string s(“abcd”);
    s.compare(“abcd”); //返回0
    s.compare(“dcba”); //返回一个小于0的值
    s.compare(“ab”); //返回大于0的值
    s.compare(s); //相等
    s.compare(0,2,s,2,2); //用”ab”和”cd”进行比较 小于零
    s.compare(1,2,”bcx”,2); //用”bc”和”bc”比较。
    怎么样?功能够全的吧!什么?还不能满足你的胃口?好吧,那等着,后面有更个性化的比较算法。先给个提示,使用的是STL的比较算法。什么?对STL一窍不通?靠,你重修吧!

    2.5 更改内容
    这在字符串的操作中占了很大一部分。
    首先讲赋值,第一个赋值方法当然是使用操作符=,新值可以是string(如:s=ns) 、c_string(如:s=”gaint”)甚至单一字符(如:s='j')。还可以使用成员函数assign(),这个成员函数可以使你更灵活的对字符串赋值。还是举例说明吧:
    s.assign(str); //不说
    s.assign(str,1,3);//如果str是”iamangel” 就是把”ama”赋给字符串
    s.assign(str,2,string::npos);//把字符串str从索引值2开始到结尾赋给s
    s.assign(“gaint”); //不说
    s.assign(“nico”,5);//把'n' ‘I' ‘c' ‘o' ‘/0'赋给字符串
    s.assign(5,'x');//把五个x赋给字符串
    把字符串清空的方法有三个:s=””;s.clear();s.erase();(我越来越觉得举例比说话让别人容易懂!)。
    string提供了很多函数用于插入(insert)、删除(erase)、替换(replace)、增加字符。
    先说增加字符(这里说的增加是在尾巴上),函数有 +=、append()、push_back()。

    举例如下:
    s+=str;//加个字符串
    s+=”my name is jiayp”;//加个C字符串
    s+='a';//加个字符
    s.append(str);
    s.append(str,1,3);//不解释了 同前面的函数参数assign的解释
    s.append(str,2,string::npos)//不解释了
    s.append(“my name is jiayp”);
    s.append(“nico”,5);
    s.append(5,'x');
    s.push_back(‘a');//这个函数只能增加单个字符对STL熟悉的理解起来很简单

    也许你需要在string中间的某个位置插入字符串,这时候你可以用insert()函数,这个函数需要你指定一个安插位置的索引,被插入的字符串将放在这个索引的后面。
          s.insert(0,”my name”);
          s.insert(1,str);
    这种形式的insert()函数不支持传入单个字符,这时的单个字符必须写成字符串形式(让人恶心)。既然你觉得恶心,那就不得不继续读下面一段话:为了插 入单个字符,insert()函数提供了两个对插入单个字符操作的重载函数:insert(size_type index,size_type num,chart c)和insert(iterator pos,size_type num,chart c)。其中size_type是无符号整数,iterator是char*,所以,你这么调用insert函数是不行的:insert(0,1, 'j');这时候第一个参数将转换成哪一个呢?所以你必须这么写:insert((string::size_type)0,1,'j')!第二种形式指 出了使用迭代器安插字符的形式,在后面会提及。顺便提一下,string有很多操作是使用STL的迭代器的,他也尽量做得和STL靠近。

    删除函数erase()的形式也有好几种(真烦!),替换函数replace()也有好几个。

    举例吧:
    string s=”il8n”;
    s.replace(1,2,”nternationalizatio”);//从索引1开始的2个替换成后面的C_string
    s.erase(13);//从索引13开始往后全删除
    s.erase(7,5);//从索引7开始往后删5个

    2.6提取子串和字符串连接
    题取子串的函数是:substr(),形式如下:
    s.substr();//返回s的全部内容
    s.substr(11);//从索引11往后的子串
    s.substr(5,6);//从索引5开始6个字符
    把两个字符串结合起来的函数是+。(谁不明白请致电120)

    2.7输入输出操作
    1.>> 从输入流读取一个string。
    2.<< 把一个string写入输出流。
    另一个函数就是getline(),他从输入流读取一行内容,直到遇到分行符或到了文件尾。

    2.8搜索与查找
    查找函数很多,功能也很强大,包括了:
    find()
    rfind()
    find_first_of()
    find_last_of()
    find_first_not_of()
    find_last_not_of()

    这些函数返回符合搜索条件的字符区间内的第一个字符的索引,没找到目标就返回npos。所有的函数的参数说明如下:
    第一个参数是被搜寻的对象。第二个参数(可有可无)指出string内的搜寻起点索引,第三个参数(可有可无)指出搜寻的字符个数。比较简单,不多说不理解的可以向我提出,我再仔细的解答。当然,更加强大的STL搜寻在后面会有提及。

    最后再说说npos的含义,string::npos的类型是string::size_type,所以,一旦需要把一个索引与npos相比,这个索引值必须是string::size)type类型的,更多的情况下,我们可以直接把函数和npos进行比较(如:if(s.find(“jia”)== string::npos))。

    string类的构造函数:
    string(const char *s);    //用c字符串s初始化
    string(int n,char c);     //用n个字符c初始化
    此外,string类还支持默认构造函数和复制构造函数,如string s1;string s2="hello";都是正确的写法。当构造的string太长而无法表达时会抛出length_error异常

    string类的字符操作:
    const char &operator[](int n)const;
    const char &at(int n)const;
    char &operator[](int n);
    char &at(int n);
    operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。
    const char *data()const;//返回一个非null终止的c字符数组
    const char *c_str()const;//返回一个以null终止的c字符串
    int copy(char *s, int n, int pos = 0) const;//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目

    string的特性描述:
    int capacity()const;    //返回当前容量(即string中不必增加内存即可存放的元素个数)
    int max_size()const;    //返回string对象中可存放的最大字符串的长度
    int size()const;        //返回当前字符串的大小
    int length()const;       //返回当前字符串的长度
    bool empty()const;        //当前字符串是否为空
    void resize(int len,char c);//把字符串当前大小置为len,并用字符c填充不足的部分

    string类的输入输出操作:
    string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作。
    函数getline(istream &in,string &s);用于从输入流in中读取字符串到s中,以换行符'\n'分开。

    string的赋值:
    string &operator=(const string &s);//把字符串s赋给当前字符串
    string &assign(const char *s);//用c类型字符串s赋值
    string &assign(const char *s,int n);//用c字符串s开始的n个字符赋值
    string &assign(const string &s);//把字符串s赋给当前字符串
    string &assign(int n,char c);//用n个字符c赋值给当前字符串
    string &assign(const string &s,int start,int n);//把字符串s中从start开始的n个字符赋给当前字符串
    string &assign(const_iterator first,const_itertor last);//把first和last迭代器之间的部分赋给字符串

    string的连接:
    string &operator+=(const string &s);//把字符串s连接到当前字符串的结尾 
    string &append(const char *s);            //把c类型字符串s连接到当前字符串结尾
    string &append(const char *s,int n);//把c类型字符串s的前n个字符连接到当前字符串结尾
    string &append(const string &s);    //同operator+=()
    string &append(const string &s,int pos,int n);//把字符串s中从pos开始的n个字符连接到当前字符串的结尾
    string &append(int n,char c);        //在当前字符串结尾添加n个字符c
    string &append(const_iterator first,const_iterator last);//把迭代器first和last之间的部分连接到当前字符串的结尾

    string的比较:
    bool operator==(const string &s1,const string &s2)const;//比较两个字符串是否相等
    运算符">","<",">=","<=","!="均被重载用于字符串的比较;
    int compare(const string &s) const;//比较当前字符串和s的大小
    int compare(int pos, int n,const string &s)const;//比较当前字符串从pos开始的n个字符组成的字符串与s的大小
    int compare(int pos, int n,const string &s,int pos2,int n2)const;//比较当前字符串从pos开始的n个字符组成的字符串与s中pos2开始的n2个字符组成的字符串的大小
    int compare(const char *s) const;
    int compare(int pos, int n,const char *s) const;
    int compare(int pos, int n,const char *s, int pos2) const;
    compare函数在>时返回1,<时返回-1,==时返回0   
    string的子串:
    string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串

    string的交换:
    void swap(string &s2);    //交换当前字符串与s2的值

    string类的查找函数: 
    int find(char c, int pos = 0) const;//从pos开始查找字符c在当前字符串的位置
    int find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
    int find(const char *s, int pos, int n) const;//从pos开始查找字符串s中前n个字符在当前串中的位置
    int find(const string &s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
    //查找成功时返回所在位置,失败返回string::npos的值 
    int rfind(char c, int pos = npos) const;//从pos开始从后向前查找字符c在当前串中的位置
    int rfind(const char *s, int pos = npos) const;
    int rfind(const char *s, int pos, int n = npos) const;
    int rfind(const string &s,int pos = npos) const;
    //从pos开始从后向前查找字符串s中前n个字符组成的字符串在当前串中的位置,成功返回所在位置,失败时返回string::npos的值 
    int find_first_of(char c, int pos = 0) const;//从pos开始查找字符c第一次出现的位置
    int find_first_of(const char *s, int pos = 0) const;
    int find_first_of(const char *s, int pos, int n) const;
    int find_first_of(const string &s,int pos = 0) const;
    //从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。查找失败返回string::npos 
    int find_first_not_of(char c, int pos = 0) const;
    int find_first_not_of(const char *s, int pos = 0) const;
    int find_first_not_of(const char *s, int pos,int n) const;
    int find_first_not_of(const string &s,int pos = 0) const;
    //从当前串中查找第一个不在串s中的字符出现的位置,失败返回string::npos 
    int find_last_of(char c, int pos = npos) const;
    int find_last_of(const char *s, int pos = npos) const;
    int find_last_of(const char *s, int pos, int n = npos) const;
    int find_last_of(const string &s,int pos = npos) const; 
    int find_last_not_of(char c, int pos = npos) const;
    int find_last_not_of(const char *s, int pos = npos) const;
    int find_last_not_of(const char *s, int pos, int n) const;
    int find_last_not_of(const string &s,int pos = npos) const;
    //find_last_of和find_last_not_of与find_first_of和find_first_not_of相似,只不过是从后向前查找

    string类的替换函数: 
    string &replace(int p0, int n0,const char *s);//删除从p0开始的n0个字符,然后在p0处插入串s
    string &replace(int p0, int n0,const char *s, int n);//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符
    string &replace(int p0, int n0,const string &s);//删除从p0开始的n0个字符,然后在p0处插入串s
    string &replace(int p0, int n0,const string &s, int pos, int n);//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符
    string &replace(int p0, int n0,int n, char c);//删除p0开始的n0个字符,然后在p0处插入n个字符c
    string &replace(iterator first0, iterator last0,const char *s);//把[first0,last0)之间的部分替换为字符串s
    string &replace(iterator first0, iterator last0,const char *s, int n);//把[first0,last0)之间的部分替换为s的前n个字符
    string &replace(iterator first0, iterator last0,const string &s);//把[first0,last0)之间的部分替换为串s
    string &replace(iterator first0, iterator last0,int n, char c);//把[first0,last0)之间的部分替换为n个字符c
    string &replace(iterator first0, iterator last0,const_iterator first, const_iterator last);//把[first0,last0)之间的部分替换成[first,last)之间的字符串

    string类的插入函数: 
    string &insert(int p0, const char *s);
    string &insert(int p0, const char *s, int n);
    string &insert(int p0,const string &s);
    string &insert(int p0,const string &s, int pos, int n);
    //前4个函数在p0位置插入字符串s中pos开始的前n个字符

    string &insert(int p0, int n, char c);//此函数在p0处插入n个字符c
    iterator insert(iterator it, char c);//在it处插入字符c,返回插入后迭代器的位置
    void insert(iterator it, const_iterator first, const_iterator last);//在it处插入[first,last)之间的字符
    void insert(iterator it, int n, char c);//在it处插入n个字符c

    string类的删除函数 
    iterator erase(iterator first, iterator last);//删除[first,last)之间的所有字符,返回删除后迭代器的位置
    iterator erase(iterator it);//删除it指向的字符,返回删除后迭代器的位置
    string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串

    string类的迭代器处理: 
    string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。

    用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:
    const_iterator begin()const;
    iterator begin();                //返回string的起始位置
    const_iterator end()const;
    iterator end();                    //返回string的最后一个字符后面的位置
    const_iterator rbegin()const;
    iterator rbegin();                //返回string的最后一个字符的位置
    const_iterator rend()const;
    iterator rend();                    //返回string第一个字符位置的前面
    rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现

    字符串流处理: 
    通过定义ostringstream和istringstream变量实现,<sstream>头文件中
    例如:
    string input("hello,this is a test");
    istringstream is(input);
    string s1,s2,s3,s4;
    is>>s1>>s2>>s3>>s4;//s1="hello,this",s2="is",s3="a",s4="test"
    ostringstream os;
    os<<s1<<s2<<s3<<s4;
    cout<<os.str();

    一直弄不清楚c++string变量中存储数字的原理,现在也是很模糊,先把知道的写上

    1如果往string变量中输入一个数字输出也是一个数字

    2如果往string变量中输入一个数字,但需要进行计算的时候需要-'0'

    3通过两个数字相加得到的第三个数字存入string中的时候,需要+'0'


    展开全文
  • C++string学习总结

    2018-11-13 08:44:49
    C++string学习总结.标准库的string类1.string类是什么?2.string类常用接口总结a.string类对象的常见构造函数b.string类对象常用的容量操作c.string类对象的访问操作d.string类对象常见的修改操作 .标准库的...
  • 某日在实现一个新功能时,在代码很不起眼的一行,调用一个接口时将其一个为string类型的形参,赋值为0。 编译通过,然后程序每次调用新功能时必Crash。 之后,通过追加Log,反复查找。最终定位到传错参数类型的...
  • C++基础之string类型

    2018-09-25 17:41:54
    C++基础之string类型 string 类型支持长度可变的字符串,C++ 标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作。标准库 string 类型的目的就是满足对字符串的一般应用。 与其他的标准库类型一样,...
  • 前言: string 的角色 1 string 使用 1.1 充分使用string 操作符 1.2 眼花缭乱的string find 函数 1.3 string insert, replace, erase 2 string 和 C风格字符串 3 string 和 Charactor Traits 4 string 建议 5...
  • C++读入一行字符串

    2019-03-14 14:42:23
    C++中,要读取一行一共三种方法 一.对于字符数组: 方法一:getline() 读入整行数据,它使用回车键输入的换行符来确定输入结尾。 调用方法: cin.getline(str, len); 第一个参数str是用来存储输入行的数组名称,...
  • C++ string 用法详解 C++ string 详解 任何人对本文进行引用都要标明作者是Nicolai M.Josuttis /////////////////////////////////////////////////////////////////////////////////// C++ 语言是个...
  • C++/C++11std::string用法汇总
  • #c++中string和c语言string用法总结 #include <string.h> //c语言的头文件 #include using namespace std;//c++语言的头文件,...C++中string相当于个类,构造函数和析构函数。 2.字符串操作函数 stri...
  • 基础 1、getchar() 头文件#include<...读入一行字符串,以换行结束。 应用:实现输入 1、读一行整数,以换行结束。便输出。 输入: 10 20 30 80 70 输出: 10 20 30 80 70 #include <iostream> #includ...
  • 1、首先是定义一个字符串,引入头文件#include。 2、初始化操作:可以默认初始化 string str; 可以进行拷贝: string s2=s1; 可以直接初始化 string s1("value");...如果想读入一行,可以用getline(cin,str);
  • c++string类型)

    2019-05-05 22:04:47
    c++对于字符串的处理提供了两种方法: 按照c的字符数组处理。 按照string类型的对象处理。 string类是种抽象数据类型(ADT),不是内嵌的、原子数据类型;和int、float、double等不同。 与字符数组...
  • 代码实例: #include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;... string str("55.5818061829 119.6388702393 22.33"); double t; istringstre...
  • 在对格式化的数据进行处理的时候,很多时候需要在字符串中进行数据的提取, 如果使用Oracle数据库,...C/C++中有sprintf方法可以把系列数字转换为字符串,也提供了从字符串中提取出数字的方法。 1. fscanf http...
  • 时候会遇到输入不确定行数字,每行输入不确定个数的情况; 发现这是个什么需求?不会呀T_T 查了半天也没有令人满意的,无意间发现可以用字符串来处理,茅塞顿开; 不废话,直接上代码: #include <...
  • stringc++中的使用

    2018-08-11 20:44:31
    字符类型和字符数组( 字符值知识点)要提前了解一下,能更好的了解string   string类型支持长度可变的字符串 在头文件 #include&lt;string&gt;   string对象的定义和初始化   string s1; ...
1 2 3 4 5 ... 20
收藏数 74,543
精华内容 29,817
关键字:

c++string一行中有数字