标准c++中string类介绍 淡淡的烟草味﹌ 2022-08-25 09:21 141阅读 0赞 **标准c++中string类介绍** # [char\*数组(c类型字符串)和c++中的string的转换、字符串比较、char\*数组等问题][char_c_c_string_char] # char ch\[100\]; string str; 把char\*(c类型的string)数组转换为string: str = ch; //即可 str.assign(ch); //也可 把string类型转换为char\*数组: strcpy(ch,str.c\_str()); //即可 for(int i = 0; i < str.length(); i++) //也可 \{ ch = str.at(i); ch ++; \} 比较两个字符串相等 string str1; string str2; strcmp(str1.c\_str(),str2.c\_str()); < 0 string1 less than string2 = 0 string1 identical to string2 > 0 string1 greater than string2 清空一个char\*数组 memset(void \*dest,int c,size\_t count) 拷贝char\*数组 memcpy(void \*dest,const void \* src,size\_t count) 判断是否是一个字符串的子串 strstr(); str.find("") 在C语言中,字符串基本就是字符型数组,并且总是以二进制零(即空结束付)作为其最末元素。C++ string类与它们在C语言中的前身截然不同,C++ string类具有很多优点: 1>. 隐藏了字符串序列内部字符序列的物理表示:也就是说程序设计人员不必关心数组维数及空结束符问题,例如当程序访问越界时,字符串内部会做自动抛出异常等处 理,而不用程序去检测是否遇到空结束符,这很大程度上隐藏了一些复杂的实现,更方便程序员使用。 ** ** 2>. 无需程序员干预,string类可以根据需要自动扩充规模:在C中,当对字符串操作时,通常需要程序员跟踪字符串的存储边界,当对一个对象扩充时,需要程 序员手动扩充存储,同时,这些令人生厌的“内务处理”琐事不仅不方便,而且不安全,C++中的string类则解决了这些问题,使用C++时会最真切的感 受到这些。 3>. 提高了便利性和安全性:在C语言中,为了实现对字符串方便的操作,提供了一系列库函数,然而但这些库函数名列表不仅冗长,而且充满了模糊不清、晦涩难懂的名字;C++通过理性化的命名机制、函数重载及默认参数解决了这些问题。 ** ** 下面将从以下四方面做更详细的介绍: ** ** 1. 创建并初始化字符串 2. 字符串操作 3 字符串比较 ** ** 4 其他常用函数介绍 **1. 创建并初始化字符串** 创建并初始化字符串至少有如下9种方法: ====================================================================================== string s; 生成一个空字符串s,并不立即初始化它 string s(“string”); 创建字符串并用引用字符数组进行初始化 string s = str; 采用重载运算符方法,用已有字符串初始化新字符串 string s(str,stridx,strlen); 将字符串str内始于stridx且长度顶多strlen的部分作为字符串的初值,其中str、stridx、strlen的默认值分别为””、0、极大整型值 string s(chars,chars\_len); 将C字符串前chars\_len个字符作为字符串s的初值,chars\_len的默认值为极大整型值 string s(num,c); 生成一个字符串,包含num个c字符 string s(s1.begin(),s1.end()); 采用迭代器方法,选取字符串区间beg-end(不包含end)内的字符作为字符串s的初值 string s = “a”+”b”; 使用operator+链接已有字符串后初始化新字符串 string s = str.substr(stridx,strlen); 使string对象的用成员函数substr()来初始化字符串,其中stridx、strlen的默认值分别为0、极大整型值 ====================================================================================== **实例1:**创建并初始化字符串 ====================================================================================== \#include <string> \#include <iostream> using namespace std; int main() \{ string s1("What is the sound of one clam napping?"); string s2("Anything worth doing is worth overdoing."); string s3("I saw Elvis in a UFO"); // Copy the first 8 chars: string s4(s1, 0, 8); string str("a new string", 5); cout << s4 << endl; // Copy 6 chars from the middle of the source: string s5(s2, 15, 6); cout << s5 << endl; // Copy from middle to end: string s6(s3, 6, 15); cout << s6 << endl; // Copy many different things: string quoteMe = s4 + "that" + // substr() copies 10 chars at element 20 s1.substr(20, 10) + s5 + // substr() copies up to either 100 char // or eos starting at element 5 "with" + s3.substr(5, 100) + // OK to copy a single char this way s1.substr(37, 1); cout << quoteMe << endl; \} ///:~ ====================================================================================== ** 2. 字符串操作** **2.1 插入、追加和连接操作(增操作)** ====================================================================================== s.insert(stridx, str ); 在指定下标stridx对应的字符前插入字符串str,即执行插入操作 s.append(str); 在指定字符串s后追加给定字符串str,如果存储规模不足,会自动扩展,即执行追加操作 a = a + str; 连接操作由重载运算符实现 =============================================================================== **实例2**:插入、追加和连接操作 ====================================================================================== \#include <string> \#include <iostream> using namespace std; int main() \{ string bigNews("I saw Elvis in a UFO. "); cout << bigNews << endl; // How much data have we actually got? cout << "Size = " << bigNews.size() << endl; // How much can we store without reallocating? cout << "Capacity = " << bigNews.capacity() << endl; // Insert this string in bigNews immediately // before bigNews\[1\]: bigNews.insert(1, " thought I"); cout << bigNews << endl; cout << "Size = " << bigNews.size() << endl; cout << "Capacity = " << bigNews.capacity() << endl; // Make sure that there will be this much space bigNews.reserve(500); // Add this to the end of the string: bigNews.append("I've been working too hard."); cout << bigNews << endl; cout << "Size = " << bigNews.size() << endl; cout << "Capacity = " << bigNews.capacity() << endl; \} ///:~ =============================================================================== **2.2 从字符串中删除字符(删操作)** =============================================================================== s.erase(stridx, strlen); 删除字符串中的字符,stridx指定删除起始位置,默认值为0,strlen表示删除字符序列个数,默认值为极大整型值 ====================================================================================== **2.3 替换字符串中的字符(改操作)** ====================================================================================== s.replace(stridx, strlen, str); 对指定下标开始到指定长度strlen区间的字符序列用字符 串str替换 ====================================================================================== **2.4 字符串的查找(查操作)** ====================================================================================== **s.**find(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找单个字符或字符串: 如果找到,返回首次匹配的开始位置;否则返回string::npos s. find\_first\_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找第一个与指定字符数组str中任何字符匹配的字符位置: 如果找到,返回第一次匹配的开始位置;否则返回string::npos s. find\_last\_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找最后一个与指定字符数组str中任何字符匹配的字符位置:如果找到,返回最后一次匹配的开始位置;否则返回string::npos。功能和find类似 s. find\_first\_not\_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找第一个不与指定字符数组str中任何字符匹配的字符位置:如果找到,返回第一次匹配的开始位置;否则返回string::npos s. find\_last\_not\_of(char|str, stridx); 在指定单词中,从指定下标stridx开始,查找最后一个不与指定字符数组str中任何字符匹配的字符位置: 如果找到,返回最后一次匹配的开始位置;否则返回string::npos。功能和find类似 s.rfind(char|str, stridx); 在指定单词中,从指定下标stridx开始,反向查找单个字符或字符串: 如果找到,返回首次匹配的开始位置;否则返回string::npos ====================================================================================== ** ** **实例3**:字符串的查找(查操作) ====================================================================================== \#ifndef SIEVE\_H \#define SIEVE\_H \#include <cmath> \#include <cstddef> \#include <string> \#include "../TestSuite/Test.h" using std::size\_t; using std::sqrt; using std::string; class SieveTest : public TestSuite::Test \{ string sieveChars; public: // Create a 50 char string and set each // element to 'P' for Prime: SieveTest() : sieveChars(50, 'P') \{\} void run() \{ findPrimes(); testPrimes(); \} bool isPrime(int p) \{ if(p == 0 || p == 1) return false; int root = int(sqrt(double(p))); for(int i = 2; i <= root; ++i) if(p % i == 0) return false; return true; \} void findPrimes() \{ // By definition neither 0 nor 1 is prime. // Change these elements to "N" for Not Prime: sieveChars.replace(0, 2, "NN"); // Walk through the array: size\_t sieveSize = sieveChars.size(); int root = int(sqrt(double(sieveSize))); for(int i = 2; i <= root; ++i) // Find all the multiples: for(size\_t factor = 2; factor \* i < sieveSize; ++factor) sieveChars\[factor \* i\] = 'N'; \} void testPrimes() \{ size\_t i = sieveChars.find('P'); while(i != string::npos) \{ test\_(isPrime(i++)); i = sieveChars.find('P', i); \} i = sieveChars.find\_first\_not\_of('P'); while(i != string::npos) \{ test\_(!isPrime(i++)); i = sieveChars.find\_first\_not\_of('P', i); \} \} \}; \#endif // SIEVE\_H ///:~ \#include "Sieve.h" int main() \{ SieveTest t; t.run(); return t.report(); \} ///:~ ====================================================================================== ** 3 字符串比较** ** ** ** ** 字符串的比较其实是进行字典比较;字典比较的意思是,当测试一个字符看它是否大于另一个字符时,时机比较的是它们的数值表示,而这些数值表示是由当前所使用的字符集的校对序列决定的,通常这种校对序列是ASCII校对序列;当字典比较报告字符串S1大于S2时,也即两者相比较时,字符串S1中第一个不同的字符比字符串S2中同样位置的字符在ASCII表中的位置更靠后。 **方法一 运算符重载** C++ string类提供了运算符重载的方法,用于比较字符串;这种方法直观而且使用方便。 **实例4:** 运算符重载 ====================================================================================== \#ifndef COMPSTR\_H \#define COMPSTR\_H \#include <string> \#include "../TestSuite/Test.h" using std::string; class CompStrTest : public TestSuite::Test \{ public: void run() \{ // Strings to compare string s1("This"); string s2("That"); test\_(s1 == s1); test\_(s1 != s2); test\_(s1 > s2); test\_(s1 >= s2); test\_(s1 >= s1); test\_(s2 < s1); test\_(s2 <= s1); test\_(s1 <= s1); \} \}; \#endif \#include "CompStr.h" int main() \{ CompStrTest t; t.run(); return t.report(); \} ///:~ ====================================================================================== **方法二 compare函数** ** ** 除运算符重载之外,可以利用compare函数进行更复杂精密的比较手段;它提供重载版本,可以比较: * 两个完整的字符串: str1.compare(str2); * 一个字符串的某一部分和另一个字符串的全部: str1.compare(stridx, strlen, str2); * 两个字符串的子串: str1.compare(stridx, strlen, str2, stridx, strlen); 其中,stridx是给定字符串进行比较部分的开始,stdlen是要比较的字符长度。 实例: compare函数 ====================================================================================== \#include <cassert> \#include <string> using namespace std; int main() \{ string first("This is a day that will live in infamy"); string second("I don't believe that this is what " "I signed up for"); // Compare "his is" in both strings: assert(first.compare(1, 7, second, 22, 7) == 0); // Compare "his is a" to "his is w": assert(first.compare(1, 9, second, 22, 9) < 0); \} ///:~ ====================================================================================== ** 4 其他常用函数介绍** ** ** 除了以上介绍到的对字符串的操作,下面对于一些经常用到的几个有意义的函数做如下解释及对比: ====================================================================================== s.size(); 返回当前在字符串中存储的字符数 s.length(); 作用等同于size()成员函数 s.capacity(); 返回为当前字符串分配的存储空间的规模,一般大于size()成员函数的返回值 s.reserve(strlen); 按照程序员的意图,预留指定长度的存储空间,此时capacity()成员函数的返回值与strlen接近:当strlen大于字符串长度时,扩充存储空间;否则不做任何处理 s.resize(strlen); 按照程序员的意图,重定义字符串: 如果strlen长度大于当前字符串长度,则在当前字符串后补空格;否则,则会截取当前字符串。resize对字符串本身操作,而reserve对存储空间操作 s.swap( str); 用于交换两个字符串的内容,参数必须为字符串型变量 s.clear(); 清空指定字符串,删除其中全部字符 s\[stridx\]; 用于元素存取,但是应该注意的是操作符\[\]并不检查索引是否有效(有效索引0~str.length()),如果索引失效,会引起未定义的行为 s.at(stridx); 用于元素存取,at()会做正确性检查,如果使用 at()的时候索引无效,会抛出out\_of\_range异常 s.empty(); 判断字符串是否为空:为空返回true,否则返回false ====================================================== [char_c_c_string_char]: http://blog.csdn.net/gukesdo/article/details/6912155
还没有评论,来说两句吧...