C++ string详解

用户程序要使用string类型对象,必须包含相关头文件。如果提供了合适的using声明,编写出来的程序将会变得简短些。

#include <string>
using std::string;

1、string对象的定义和初始化
常用的构造函数:
string s1; 默认构造函数,s1为空串
string s2(s1); 将s2初始化为s1的一个副本
string s3(“value”); 将s3初始化为一个字符串字面值副本
string s4(n, ‘c’); 将s4初始化为字符’c’的n个副本
注意:因为历史原因以及为了与C语言兼容,字符串字面值与标准库string类型不是同一种类型,这一点很容易引起混乱,编程时一定要注意区分字符串字面值和string数据类型的使用,这很重要。
2、string对象的读写

//Note: #include and using declarations must be added to compile this code 
int main()
{
    string s;
    cin >> s;
    cout << s << endl;
    return 0;
}

从标准输入中读取string,并将读入的串存储在s中。string类型的输入操作符:

  • 读取并忽略开头所有的空白字符(如空格,换行符,制表符)。
  • 读取字符直到再次遇到空白字符,读取终止。

    用getline读取整行文本
    getline, 这个函数接受两个参数:一个输入流对象和一个string对象。getline函数从输入流的下一行读取,并保存读取的内容到string中,但不包括换行符。和输入操作符不一样的是,getline并不忽略开头的换行符。只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回。如果第一个字符就是换行符,则string参数将被置为空string。

int main()
{
    string line;
    //read line at time until end-of-file
    while (getline(cin, line))
        cout << line << endl;
    return 0;
}

注意:由于getline函数返回时丢弃换行符,换行符将不会存储在string对象中。

3、string对象的操作

  • s.empty() 如果s为空串,则返回true, 否则返回false
  • s.size() 返回s中字符的个数
  • s[n] 返回s中位置为n的字符,位置从0开始计数
  • s1 + s2 把s1和s2连接成一个新字符串,返回新生成的字符串
  • s1 = s2 把s1内容替换为s2的副本
  • s1 == s2 比较s1和s2的内容,相等则返回true,否则返回true
  • != , <, <=, > , >=保持这些操作符惯有的含义
    关于size操作:size操作返回的是string::size_type类型的值。string类类型和许多其它库类型都定义了一些配套类型(companion type)。通过这些配套类型,库类型的使用就能与机器无关(machine-independent)。size_type 就是这些配套类型中的一种。它定义为与unsigned型(unsigned int 或 unsigned long)具有相同的含义,而且可以保证足够大能够存储任意string对象的长度。为了使用由string类型定义的size_type类型,程序员必须加上作用域操作符来说明所使用的size_type类型是由string类定义的。
    任何存储string的size操作结果的变量必须为string::size_type类型。特别重要的是,不要把size的返回值赋给一个int变量。

和字符串字面值得连接:当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个string类型的:

string s1 = "hello";        //no punctuation
string s2 = "world";
string s3 = s1 + ", ";          //ok: adding a string and literal
string s4 = "hello" + ", ";     //error: no string operand
string s5 = s1 + ", " + "world";    //ok: each + has string operand
string s6 = "hello" + ", " + s2;    //error: can't add string literals
string s7 = "hello" + s2            //ok

4、从string对象获取字符
string类型通过下标操作符([])来访问string对象中的单个字符。下标操作符需要取一个size_type类型的值,来标明要访问字符的位置。

string str("some string");
for (string::size_type ix = 0; ix != str.size(); ++ix) {
    cout << str[ix] << endl;
}

5、string对象中字符的处理

  • isalnum(c) 如果c是字母或数字, 则为true
  • isalpha(c) 如果c是字母,则为true
  • iscntrl(c) 如果c是控制字符, 则为true
  • isdigit(c) 如果c是数字,则为true
  • isgraph(c) 如果c不是空格,但可打印,则为true
  • islower(c) 如果c是小写字母,则为true
  • isprint(c) 如果c是可打印的字符,则为true
  • ispunct(c) 如果c是标点符号,则为true
  • isspace(c) 如果c是空白字符,则为true
  • isupper(c) 如果c是大写字母,则为true
  • isxdigit(c) 如果c是十六进制数,则为true
  • tolower(c) 如果c是大写字母,则返回其小写字母形式,否则直接返回c
  • toupper(c) 如果c是小写字母, 则返回其大写字母形式,否则直接返回c
    以上这些函数都在cctype头文件中定义。

6、string子串问题
截取子串
s.substr(pos, n) 截取s中从pos开始(包括0)的n个字符的子串,并返回
s.substr(pos) 截取s中从pos开始(包括0)到末尾的所有字符的子串,并返回

替换子串
s.replace(pos, n, s1) 用s1替换s中从pos开始(包括0)的n个字符的子串
s.replace(pos, n, s1, m) 用s1的从位置m到结束位置的字符替换s中从pos开始的n个字符的子串

查找子串
s.find(s1) 查找s中第一次出现s1的位置,并返回,如果s1没有出现,返回-1
s.rfind(s1) 查找s中最后一次出现s1的位置
s.find_first_of(s1) 查找在s1中任意一个字符在s中第一次出现的位置,并返回
s.find_last_of(s1) 查找在s1中任意一个字符在s中最后一次出现的位置,并返回
s.find_first_not_of(s1) 查找s中第一个不属于s1中的字符的位置,并返回
s.find_last_not_of(s1) 查找s中最后一个不属于s1中的字符的位置,并返回

插入子串
s.insert(pos, s1) 从位置pos开始添加字符串s1,并返回形成的新字符串
s.insert(pos, s1, m) 从位置pos开始添加字符串s1的从位置m到结束的字符,并返回形成的新字符串
s.insert(pos, s1, m, n) 从位置pos开始添加字符串s1[m, m+n-1],并返回形成的新字符串

追加
重载的+操作符 s += s1
s.push_back(‘c’)
s.append(“abc”)

删除
s.erase(pos) 删除位置pos及以后的字符,并返回新字符串
s.erase(pos, n) 删除pos开始的n个字符,并返回新的字符串

交换
s.swap(s1) 把s与s1交换

8、string与int的互相转换
核心:利用stringstream流

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    stringstream stream;
    int n;
    string str;

    //string 转int
    stream << "1234";   //向stream中插入字符串"1234"
    stream >> n;        //从stream中提取刚插入的字符串“1234” 并将其赋予变量n完成字符串到int的转换
    cout << n << endl;  

    stream.clear();     //同一stream进行多次转换应调用成员函数clear

    //int 转 string
    stream << 1234;     //向stream中插入整形数1234
    stream >> str;      //从stream中提取刚插入的整型数,并将其赋予变量str完成整型数到string的转换
    cout << str << endl;
    return 0;
}

stringstream转换方法简便,但是转换速度较慢。C library中的sprintf, sscanf相对更快些
可以用sprintf函数将数字输出到一个字符缓冲区中,从而进行了转换
char buf[100];
int n;
string s;
sprintf(buf, “%d”, n);
s = buf;

sscanf将字符串转换成数字
char s[] = “3.1415”;
int n;
float fn;
sscanf(s, “%d”, &i); //将字符串转换成整数n=3
sscanf(s, “%f”, &fn); //将字符串转成浮点数fn=3.141500

9、string中c_str(), data(), copy(p, n)函数的用法
标准库的string类提供了3个成员函数来从一个string得到c类型的字符数组: c_str(), data(), copy(p, n).
1)、c_str(): 生成一个const char*指针,指向以空字符终止的数组。
注意:这个数组的数据是临时的,当有一个改变这些数据的成员函数被调用后,其中的数据就会失效。因此需要把它的数据复制到用户自己可以管理的内存中。如:

const char * c;
string s = "1234";
c = s.c_str();
cout << c << endl;  //输出: 1234
s = "abcd";
cout << c << endl;  //输出: abcd

正确方式如下:

char* c = new char[20];
string s = "1234";
strcpy(c, s.c_str());
cout << c << endl;      //输出: 1234
s = "abcd";
cout << c << endl;      //输出: 1234

注意:c_str()返回一个客户程序可读不可改的指向字符数组的指针,不需要手动释放或删除这个指针。
2)、data(): 与c_str()类似,但是返回的数组不以空字符终止。
3)、copy(p, n, size_type_off = 0): 从string类型对象中至多复制n个字符到字符指针p指向的空间中。默认从首字符开始,但是也可以指定开始的位置(从0开始编号),返回真正从对象中复制的字符。用户要确保p指向的空间足够保存n个字符。

参考文章:
子串问题参考文章:https://www.renfei.org/blog/introduction-to-cpp-string.html
http://blog.youkuaiyun.com/ezhou_liukai/article/details/13779091
sprintf()函数的使用参考文章:http://blog.youkuaiyun.com/bat67/article/details/52063813
c_str(), data(), copy(p, n)参考文章:http://www.cnblogs.com/qlwy/archive/2012/03/25/2416937.html
在此向作者表示感谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值