c++ 中string类的学习
1. string类的构造函数
构造函数 | 描述 |
---|---|
string(const char *s) | 将string对象初始化为s指向的NBTS(表示以空字符结束的字符串) |
string(size_type n,char c) | 创建一个大小为n的string对象,并且每个元素都被初始化为字符c |
string(const string & str) | 将一个string对象初始化为string对象str(复制构造函数) |
string() | 创建一个默认的string对象,长度为 0 (默认的构造函数) |
string(const char * s,size_type n) | 将string对象初始化为s的前n个字符,即使超过了结尾 |
template< class Iter> , string(Iter begin,Iter end) | 将string对象初始化为区间[begin ,end)内的字符,begin,end的行为就像指针 |
string(const string & str, size_type pos=0,size_type n=npos) | 将string对象初始化为str从pos开始的n个字符 |
string(string && str) | C++ 11 新增,将一个string对象初始化为string 对象 str. |
string(initializer_list< char> il) | C++ 11 新增,将string对象初始化为初始化列表 il 中的字符 |
开始做一下练习:
#include <iostream>
#include <cstring>
//using string constructors
using namespace std;
int main()
{
string one("hello world!"); //ctor # 1
cout << one << endl;
string two(20, '&'); //ctor #2
cout << two << endl;
string three(one); //ctor #3
cout << three <<endl;
one += " what!"; //overloaded +=
cout << one << endl;
two = "sorry, that is";
three[0] = 'H';
string four; //ctor #4
four = two + three; //overloaded + =
cout << four << endl;
char alls[] = "All is well that ends well";
string five(alls, 20); //ctor #5
cout << five << endl;
string six(alls+6, alls+20); //ctor # 6
cout << six << endl;
string seven(&five[6],&five[20]); // ctor #6 again
cout << seven << endl;
string eight(four, 7, 13); //ctor #8
cout << eight << endl;
return 0;
}
结果如下:
构造函数记住常用的几个即可,做题的时候可以成为一种工具!!!!
2. string对象的输入
2.1对于c-风格字符串,有3种方式:
char info[100];
cin >> info; //read a word
cin.getline(info, 100); //read a line, discard \n
cin.get(info , 100); //read a line, leave \n in queue
2.2 对于string对象,有两种方式
string stuff;
cin >> stuff ; //read a word;
getline(cin ,stuff); //read a line, discard \n
string版本的getline()将自动调整string对象的大小,使之刚好能够存储输入的字符。
具体分析cin、 cin.getline() 、 getline() 的用法区别,参考:
https://blog.csdn.net/qq_22613757/article/details/83792747
注: cin.get() cin.getline()区别
分为三种情况来看:
1)输入的字符串不超过限定大小
get(str,Size):读取所有字符,遇到’\n’时止,并且将’\n’留在输入缓冲区中,其将被下一个读取输入的操作捕获,影响该输入处理;
getline(str,Size):读取所有字符,遇到’\n’时止,并且将’\n’直接从输入缓冲区中删除掉,不会影响下面的输入处理。
2)输入的字符数超出限定的大小
get(str,Size):读取Size-1个字符,并将str[Size-1]置为’\0’,然后将剩余字符(包括’\n’)留在输入缓冲区中,这些字符将被下一个读取输入的操作捕获,影响该输入处理;
getline(str,Size):读取Size-1个字符,并将str[Size-1]置为’\0’,剩余字符(包括’\n’)留在输入缓冲区中,随即设置cin实效位(即if(!cin)的判断为真),关闭输入。其后的所有输入都无法得到任何东西,当然也无法得到输入缓冲区中剩余的字符串。但如果象本例一样用clear()重置cin,其后的输入便可用并会得到遗留在输入缓冲区中的字符。
3)输入一个空行(即直接回车)
get(str,Size):str将得到’\0’,并设置cin实效位,关闭输入,但回车依然留在输入缓冲区中,因此如果我们用clear()重置cin,其下一个读取输入的操作将捕获’\n’;
getline(str,Size):str将得到’\0’,并将’\n’删除掉,不置实效位,不关闭输入。所以对于cin.getline来说空行是合法的输入,且不会影响下面的输入处理。
至于使用那个更好,可能因人习惯不同而不同,仁者见仁智者见智。对于我们编程来说,总希望能有更好的容错性,即便用户输入了不合理的输入,程序也应该能够 提示并能够重新输入或继续正常处理,而因为用户的输入问题而导致程序错误或其后的所有输入都不可用显然不是我们希望的。使用get(str,Size)和 getline(str,Size),都可能碰到设置失效位,关闭输入的情况,故都是需要考虑到相应的防错处理的。
2.3 string对象读取文件
用于string对象的输入函数使用输入流,能够识别文件尾,因此也可以使用它们从文件中读取输入。例:
#include <iostream>
#include <cstring>
#include <fstream>
#include <cstdlib>
using namespace std;
int main()
{
/**读文件*/
ifstream fin;
fin.open("tobuy.txt");
if(fin.is_open() == false)
{
cerr << "Can't open file, bye!\n";
exit(EXIT_FAILURE);
}
string item;
int count = 0;;
getline(fin, item, ':');
while(fin)
{
++count;
cout << count << ":" << item << endl;
getline(fin, item, ':');
}
cout << "done\n";
fin.close();
return 0;
}
文件内容:
结果:
使用:定为分界字符后,换行符将被视为常规字符。因此文件中第一行末尾的 换行符将成为包含“wozhendel”的字符串的第一个字符。
3. string 对象的使用
除了以上介绍的所有操作外,string类对象还可以进行很多其他操作:
- 比较字符串
string 类对6个关系运算符都进行了重载,可以进行大小的比较。
对于每个关系运算符,都以三种方式进行重载,以便能够将string对象与另一个string对象,C-风格字符串进行比较,并能够将C-风格字符串与string对象进行比较:
string snake1(“cobra”);
string snake2(“cora1”);
char snake3[20] = “anaconda”;
if(snake1 < snake2) // operator<(const string &,const string &)
…
if(snake1 == snake3 ) // operator = = (const string &,const char *)
…
if(snake3 != snake2) // operator != (const char *, const string &)
… - size()和length()函数
- find()方法
方法原型 | 描述 |
---|---|
size_type find(const string &str, size_type pos=0)const | 从字符串的pos位置开始,查找子字符串str。如果找到,则返回子字符串第一次出现时首字符的索引,否则,返回str::npos |
size_type find(const char * s, size_type pos=0)const | 从字符串的pos位置开始,查找子字符串str,如果找到,则返回子字符串第一次出现时首字符的索引,否则,返回,str::npos |
size_type find(const char *s, size_type pos = 0,size_type n) | 从字符串的pos位置开始,查找s的前n个字符组成的子字符串。如果找到,则返回该子字符串首次出现时其首字符的索引;否则,返回 string::npos |
size_type find(char ch,size_type pos =0) const | 从字符串的pos位置开始,查找字符ch。如果字符ch。如果找到,则返回该字符首次出现的位置,否则,返回 string::npos |
string 库还提供相关方法: rfind()、find_first_of()、find_last_of()、find_first_not_of()和find_last_not_of(),它们在重载函数特征都与find()方法相同,rfind()查找子字符串或字符最后一次出现的位置,find_fist_of()方法在字符串查找参数中任何一个字符首次出现的位置。find_last_of()相似。find_first_not_of()查找字符串中查找第一次不包含参数出现的位置。同理find_last_not_of().
capacity()返回当前分配给字符串的内存块的大小;
reserve() 方法返回能够请求内存块的最小长度;
如果有string对象,但需要C-风格字符串,该如何办:
例如:
string filename;
cin >> filename;
ofstream fout;
open()方法要求使用一个C-风格字符串作为参数,幸运的是,c_str()方法返回一个指向C-风格字符串指针。
fout.open(filename.c_str());