zoukankan      html  css  js  c++  java
  • 深入剖析C++中的string类

    comments:本文摘自于网络

    一,C语言的字符串

    在C语言里,对字符串的处理一项都是一件比较痛苦的事情,因为通常在实现字符串的操作的时候都会用到最不容易驾驭的类型——指针。

    比如下面这个例子:

    //example 1:

    char str[12] = "Hello";

    char *p = str;

    *p = ''h'';  //改变第一个字母

    //example 2:

    char *ptr = "Hello";

    *ptr = ''h'';  //错误

    第一个字符串时用数组开辟的,它是可以改变的变量。而第二个字符串则是一个常量,也就是字面值。ptr只是指向它的指针而已,而不能改变指向的内容。

    看两者的汇编即可明了:

    char p[] = "Hello";
    004114B8  mov         eax,dword ptr [string "Hello" (4166FCh)]
    004114BD  mov         dword ptr [ebp-10h],eax
    004114C0  mov         cx,word ptr ds:[416700h]
    004114C7  mov         word ptr [ebp-0Ch],cx

    char *ptr = "Hello";
    004114CB  mov         dword ptr [ebp-1Ch],offset string "Hello" (4166FCh)

    可见用数组和用指针是完全不相同的。

    要想通过指针来改变常量是错误,正确的写法应该是用const指针。

    const char *ptr = "Hello";

    二,初识string类

    正是因为C风格字符串(以空字符结尾的字符数组)太过复杂难于掌握,不适合大程序的开发,所以C++标准库定义了一种string类,定义在头文件<string>。注意<string.h>和<cstring>都是错误的,这两个头文件主要定义C风格字符串操作的一些方法,譬如strlen(), strcpy()等。第一个是C的头文件格式,而第二个是C++风格的头文件,但是和<string.h>是一样的,它的目的是为了和C兼容。

    看下面例子:

    //example 3:

    string str("world");   //可以用C风格字符串初始化

    string words = "Hello";

    string greet = words;

    string  join = greet + words;  //可以像基本类型一样操作

    但是如果试图把string类型的对象直接赋给C风格的字符串的话,编译器会报错的。

    string var = "Olympic";

    char *ptr = var;  //error!

    但是实际应用中这个问题也难以避免,很多时候我们还是需要将string类型的转化为char*来实现自定义的操作,C++标准库也为了和之前用C写的程序兼容,于是可以用string的c_str()函数。

    string var = "Olympic";

    char *ptr = var.c_str(); //还不能被编译

    或者通过const_cast去掉其const属性亦可

    char *ptr=const_cast<char *>(var.c_str()); //correct!

    这样就可以通过ptr修改其指向的地址空间内容

    但是c_str()为了防止意外地修改string对象,返回的是const指针,所以上面这段代码是不能被编译的。正确的应该是用const指针。

    string var = "Olympic";

    const char *p = var.c_str(); //Correct!

    这个c_str()方法在C++IO流操作上也被广泛应用。

    在打开文件时,如果要指定文件名,可以用C风格的字符串。如果用到string类型的字符串作为文件名时,就必须调用c_str()方法将其转换为一个C风格字符串。

    //example 4:

    string   filename;  //定义文件名称

    cin >> filename;

    ifstream.open(filename.c_str());  //要使用C风格字符串

    三, 深入了解string类

    对string有一定了解以后,我们可以来了解C++标准库定义的一系列丰富的字符串操作,当然都是基于string类型。从某一种程度上来说,string就是一种字符容器。

    标准库为string定义了很多方法,包括构造、插入(insert)、替换(assign和replace)、比较(compare)、查找(find)、删除(erase)、连接(append)以及对子串的操作(substr)。而每一种操作都有很多种重载。

    比如插入,除了包括标准容器的插入方式以外,string类本身还有一些特有的插入方法。

    //example 5:

    //与标准容器相同的插入操作:

    str.insert(iter, value) //在迭代器iter之前插入value, 返回新元素的迭代器

    str.insert(iter, n, value); //在迭代器iter之前插入n个value,返回void

    str.insert(iter, begin, end); //在迭代器iter之前插入迭代器begin和end标记范围内的元素,返回void

    //string类特有的插入方法:

    str.insert(pos, n, ch); //在下标为pos的字符之前插入n个字符ch

    str.insert(pos, str2); //在下标为pos的字符之前插入string类型的对象str2的副本

    str.insert(pos1, str2, pos2, len); //在下标为pos1的z字符之前插入string类型str2中从下表为pos2开始的len个字符

    str.insert(pos, cp); //在下标为pos的字符前插入字符指针cp指向的C风格字符串的副本

    总之string是一种非常灵活的字符串类型,标准库让我们可以忽略内存管理和具体实现方式,我们只需要关注其接口就好。并且初学者在使用字符串的时候也应尽量使用这种类型,而不是C风格的字符串。

    当然,无C语言学习经历的人可以例外。

  • 相关阅读:
    常见寻找OEP脱壳的方法
    Windows内核原理系列01
    HDU 1025 Constructing Roads In JGShining's Kingdom
    HDU 1024 Max Sum Plus Plus
    HDU 1003 Max Sum
    HDU 1019 Least Common Multiple
    HDU 1018 Big Number
    HDU 1014 Uniform Generator
    HDU 1012 u Calculate e
    HDU 1005 Number Sequence
  • 原文地址:https://www.cnblogs.com/Winston/p/1246677.html
Copyright © 2011-2022 走看看