C++基础之字符串


前言

个人学习笔记


一、C风格字符串

       C风格字符串以’\0’(空字符)结尾,其中C语言定义字符串有2种形式:一是字符数组(char str[]);二是字符指针(char *pstr)。对于函数而言,函数名,就是函数的入口地址;同样,数组名,就是数组的入口地址,对于字符数组而言,它的内容可以更改,但是本身不能更改。与字符数组相反,字符指针的内容不可以更改,但是本身可以更改,是一个常量指针,所以用字符指针定义C风格字符串时,会加一个const,表明这是一个常量,其内容不可以更改。对字符串进行操作的C函数定义在头文件<string.h>或<cstring>(对C标准库中<string.h>的封装)中,有以下常用操作:

函数功能
strlen(const char *str)返回字符串的长度,不包括字符串结尾的空字符
sizeof(const char *str)1、字符数组定义字符串时,返回字符串长度,包括字符串结尾的空字符;2、字符指针定义字符串时,需要注意的是返回的是指针的长度(在64位系统中,占8个字节),所以返回的并不是字符串的真正长度。
int strcmp(const char *lhs, const char *rhs)比较lhs和rhs是否相同,lhs等于rhs,返回0;lhs大于rhs,返回正数;lhs小于rhs,返回负数
char *strchr(const char *str, int ch)在str中查找首次出现ch字符的位置,若查找不到,则返回空指针。
char *strstr(const char *str, const char *substr)在str中查找首次出现子串substr的位置,若查找不到,则返回空指针。
char *strcpy(char *dest, const char *src)将src复制给dest,返回dest
char *strcat(char *dest, const char *src)把src所指向的字符串追加到dest所指向的字符串的结尾,返回dest

       strcpy(char *dest, const char *src)拷贝字符串时,如果被拷贝的字符串(src)的长度大于拷贝字符串(dest)的长度,就会发生内存越界,踩踏了其他程序的内存空间,安全性不高,所以可以通过strncpy(char *dest, const char *src, size_t n)指定拷贝的长度,这样就不会发生内存越界。
代码如下(示例):

#include <string.h>//C的头文件,定义的是一些对C风格字符串的处理函数。
#include <stdlib.h>
#include <iostream>
#include <string>//C++头文件,通过模板编写
//标准命名空间
using std::cout;
using std::endl;
using std::string;//把string的实体从标准命名空间std引出来
void test1()
{
    char str1[] = "11111";

    char *pstr = "22222";
    //C语言拼接字符串
    size_t len1 = sizeof(str1);
    size_t len2 = strlen(pstr);

    size_t len = len1 + len2;
    char *pstr1 = static_cast<char *>(malloc(len));
    memset(pstr1, 0, len);
    strcpy(pstr1, str1);
    strcat(pstr1, pstr);

    printf("pstr1 = %s\n", pstr1);
    free(pstr1);
    pstr1 = nullptr;
    
    cout << strlen(pstr) << endl;
    cout << sizeof(pstr) << endl;
     
    cout << strlen(str1) << endl;
    printf("len1 = %lu\n", len1);
    cout << len1 << endl;
}
void test2()
{
    char str1[] = "hello";
    char str2[] = "world";

    str1[0] = 'H';
    printf("str1 = %s\n", str1);
    /* str1 = nullptr; */ //error

    const char *pstr = "1234";
    printf("pstr = %s\n", pstr);
    pstr = "aaaaaaa";
    printf("pstr = %s\n", pstr);

    /* pstr[0] = 'A'; */
    printf("pstr = %s\n", pstr);
}
int main()
{
    test2();
    return 0;
}

二、C++风格字符串

       C++提供了std::string类用于字符串的处理,string类定义在C++头文件<string>中,C++支持C风格字符串,但在C++程序中最好还是不要使用它们。因为C风格字符串使用起来不太方便,容易引发程序漏洞,是很多安全问题的根本原因。与C风格字符串相比,C++风格字符串不必考虑内存、字符串长度、结尾的空字符等。并且string作为一个类出现,其集成的成员操作函数功能强大,几乎能满足所有的需求。从另一个角度上说,完全可以把string当成是C++的内置数据类型,放在和int、double等内置类型同等位置上。string类本质上其实是basic_string类模板关于char型的实例化。
       需要注意的是,C风格字符串可以转为C++风格字符串(隐式转换),而C++风格字符串转为C风格字符串需要通过对象运算符. ,通过对象运算符.调用成员函数c_str()。
       string对象可以使用下标操作符[]和函数at()对字符串中包含的字符进行访问。需要注意的是操作符[]并不检查索引是否有效,如果索引超出范围,会引起未定义的行为。而at()会检查,如果使用at()的时候索引无效,会抛出out_of_range异常。除此以外,还可以使用迭代器进行遍历访问。

代码如下(示例):

#include <string.h>//C的头文件
#include <stdlib.h>
#include <iostream>
#include <string>//C++头文件,通过模板编写
//标准命名空间
using std::cout;
using std::endl;
using std::string;//把string的实体从标准命名空间std引出来

//C++风格字符串
void test3()
{   //1、可以从C风格字符串可以转为C++风格字符串
    //     C++     C
    string s1 = "hello";
    string s2 = "world";
    string s3 = s1 + s2;//不用考虑与内存相关的概念
    cout << "s1 = " << s1 << endl
         << "s2 = " << s2 << endl
         << "s3 = " << s3 << endl;
    cout << endl;

    //2、C++风格字符串转为C风格字符串
    /* const char *pstr = s3; */ //error
    const char * pstr = s3.c_str();// 这个.是对象运算符,对象通过.调用成员函数
    cout << "pstr = " << pstr << endl;
    cout << endl;
    
    //3、获取C++风格字符串的长度
    size_t len1 = s3.size();
    size_t len2 = s3.length();
    cout << "len1 = " << len1 << endl
         << "len2 = " << len2 << endl;

    //4、遍历C++风格字符串
    for(int idx = 0; idx != s3.size(); ++idx)
    {
        cout << s3[idx] << " " ;
    }
    cout << endl;
    //迭代器遍历
    string::iterator it = s3.begin();
    while(it != s3.end())
    {
        cout << *it << " ";
        ++it;
    }
    
    //5、C++风格字符串的拼接
    string s4 = s3 + "s3";
    cout << "s4 = " << s4 << endl;

    string s5 = s4 + 'A';
    cout << "s5 = " << s5 << endl;
    string s6 = 'A' + s5;
    cout << "s6 = " << s6 << endl;
    s6.append(s1);
    cout << "s6 = " << s6 << endl;
    
    //6、查找字串
	size_t pos = s6.find("world");
	cout << "pos = " << pos << endl;
	
	//7、截取子串
	string substr = s6.substr(pos);
	cout << "substr = " << substr << endl;

}
int main()
{
    test3();
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值