string

string

1
2
3
4
5
6
7
8
string a, b;
.....
a = a + b;//将a+b前后连接,对于string来说有些符号重载定义
// ‘ + ’暂且理解为前后连接,所以前后不同,结果不同
//string作为容器,可以和字符串、字符相加,也可以和string相加
//连接的话 s += a; 这个是把往后面连接,s = a + s;这是是把字符串a连接到s的前面
//具体原因不知道
//待续
  • string是类,与c中字符串不一样,string a ="hello"+"world";错误,因为两个字符串都不是string类
  • string 的末尾没有'\0'字符,所以length()返回的是字符串的真实长度,而不是长度 +1。
  • string 字符串的起始下标仍是从 0 开始。
  • 有了 string 类,我们可以使用+或+=运算符来直接拼接字符串,非常方便,再也不需要使用C语言中的 strcat()、strcpy()、malloc() 等函数来拼接字符串了,再也不用担心空间不够会溢出了。
    • 用+来拼接字符串时,运算符的两边可以都是 string 字符串,也可以是一个 string 字符串和一个C风格的字符串,还可以是一个 string 字符串和一个字符数组,或者是一个 string 字符串和一个单独的字符。
  • string a;变量 a 只是定义但没有初始化,编译器会将默认值赋给 a,默认值是” “,也即空字符串。
    • std::string 不可以与null相比较,可以与” “比较,判空a.empty()函数,a.length() == 0
  • 使用C语言中的 fopen() 函数打开文件,必须将 string 字符串转换为C风格的字符串。

    输入

    用scanf

    1
    2
    3
    4
    5
    6
    7
    string a;
    a.resize(100); //需要预先分配空间
    //scanf是标准输入流,没有缓存区,需要预先分配空间,而cin是输入流,它使用了缓冲区。如果要使用scanf读入字符串,那就一定要事先为它申请足够的内存空间
    scanf("%s", &a[0]);
    // 输入数据中,超出指定个数的部分会被自动裁去。
    printf("%s\n", a.c_str());
    return 0;

标题没想好

  • printf只能输出C语言内置的数据,而string不是内置的,只是一个扩展的类,这样肯定是链接错误的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //printf输出string类型应如此操作!
    #include<iostream>
    #include<string>
    using namespace std;
    void main()
    {
    string s="qqq";
    printf("%s", s.c_str()); //不推荐
    //或者cout<<a;
    }
  • c_str该函数能够将 string 字符串转换为C风格的字符串,并返回该字符串的 const 指针(const char*),可读不可改的指向字符数组的指针,不需要手动释放或删除这个指针

  • c_str():生成一个const char*指针,指向以空字符终止的数组。这个数组的数据是临时的,当有一个改变这些数据的成员函数被调用后,其中的数据就会失效。因此要么现用先转换,要么把它的数据复制到用户自己可以管理的内存中。看下例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    const char* c;
    string s="1234";
    c = s.c_str();
    cout<<c<<endl; //输出:1234
    s="abcd";
    cout<<c<<endl; //输出:abcd


    //const char* c; //①
    //char* c; //②
    //char c[20];
    char* c=new char[20];
    string s="1234";
    //c = s.c_str();
    strcpy(c,s.c_str());
    cout<<c<<endl; //输出:1234
    s="abcd";
    cout<<c<<endl; //输出:1234
    //注意:不能再像上面一样①所示了,const还怎么向里面写入值啊;也不能②所示,使用了未初始化的局部变量“c”,运行会出错的 。
  • 在C语言中只有char 和 const char,为了使用起来方便,string提供了三个函数满足其要求:

      1. const charT* c_str()
      1. const const charT* data()
      1. const size_type copy(charT* buf, size_type n, size_type pos = 0)
  • 其中:

    • c_str 直接返回一个以/0结尾的字符串。 大小为size()+1.
    • data 直接以数组方式返回string的内容,其大小为size()的返回值,结尾并没有/0字符。
    • copy 把string的内容拷贝到buf空间中。
  • string的c_str()函数是用来得到C语言风格的字符串,其返回的指针不能修改其空间。而且在下一次使用时重新调用获得新的指针。

  • string的data()函数返回的字符串指针不会以’/0’结束,千万不可忽视。
  • 一定要使用strcpy()函数 等来操作方法c_str()返回的指针。c_str()返回的是字符串的首地址,返回值类型const char *的.如果要使用它并对其进行赋值操作,必须要使用strcpy函数.c_str()返回的是一个临时指针,不能对其进行操作。
    1
    2
    3
    char c[20];
    string s="1234";
    strcpy(c,s.c_str());

std::to_string()

1
2
3
4
5
6
7
8
9
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
  • to_string(1+2+4+7+14)

string类型转换int类型

1
2
3
4
5
std::string str;
int i = atoi(str.c_str());

std::string str;
int i = std::stoi(str);
  • stoi,stol,stoll等函数,表面简写原意string to …

函数

find函数

  • 查找字符串a是否包含子串b,不是用strA.find(strB) > 0而是strA.find(strB) != string:npos
    • 也最好不要用strA.fine(strB) < strA.length(),因为查找失败返回string::npos,npos是-1或很大的值

rfind() 函数

  • rfind()find() 很类似,同样是在字符串中查找子字符串,不同的是 find() 函数从第二个参数开始往后查找,而 rfind() 函数则反向查找,rfind()是从指定位置起反向查找,直到串首,失败返回string::npos。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <iostream>
    #include <string>
    using namespace std;
    int main(){
    string s1 = "first second third";
    string s2 = "second";
    int index = s1.rfind(s2,6);
    if(index < s1.length())
    cout<<"Found at index : "<< index <<endl;
    else
    cout<<"Not found"<<endl;
    return 0;
    }

find_first_of() 函数

  • 返回s2中任意字符 在s1 中第一次出现的下标位置
  • find_first_of()在源串中从位置pos起往后查找,只要在源串中遇到一个字符,该字符与目标串中任意一个字符相同,就停止查找,返回该字符在源串中的位置;若匹配失败,返回npos
  • 如果str1中含有str2中的任何字符,则就会查找成功,而find则不同

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <iostream>
    #include <string>
    using namespace std;
    int main(){
    string s1 = "first second second third";
    string s2 = "asecond";
    int index = s1.find_first_of(s2);
    if(index < s1.length())
    cout<<"Found at index : "<< index <<endl;
    else
    cout<<"Not found"<<endl;
    return 0;
    }

    运行结果:
    Found at index : 3
  • 查找s 中flag 出现的所有位置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    flag="a";
    position=0;
    int i=1;
    while( (position=s.find_first_of(flag,position) )!=string::npos)
    {
    //position=s.find_first_of(flag,position);
    cout<<"position "<<i<<" : "<<position<<endl;
    position++;
    i++;
    }

find_last_of()

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

find_first_not_of()

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

find_last_not_of()

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

assgin()

  • 将字符串2从第m个字符开始的n个字符赋值给字符串1:字符串1.assign(字符串2, m, n);
    1
    2
    3
    4
    5
    string s1 = "I'm ";
    string s2 = "1234Juruo1234";
    s1.assign(s2, 4, 5);
    cout << s1;
    //输出结果:Juruo

append()

  • 将字符串2接到字符串1尾部:字符串1.append(字符串2);字符不可以
    `c++
    将字符串2从第m个字符开始的n个字符接到字符串1尾部:
    字符串1.append(字符串2, m, n);

string s1 = “I’m “;
string s2 = “1234Juruo1234”;
s1.append(s2, 4, 5);
cout << s1;
//输出结果:I’m Juruo
`

------ The Happy Ending ------