C和C++中的字符串处理

字符串和字符数组

1. char[]、char*

  • char*是字符指针,可以指向一片内存,内存中存放着字符串;可以通过以下两种形式初始化:

    char * myStr = "Hello!";//方法一
    char *myStr1; //方法二
    myStr1 = "Hello!";
    
  • char []是字符数组,与一维数组类似;可以通过以下两种方式初始化:

    char myStr[10] = "Hello!"; //方法一
    char myStr1[10] = {'H', 'e', 'l', 'l', 'o', '!', '\0'};//方法二,结尾必须有'\0',整数0,非字符0;
    
  • 错误的定义/初始化方式:

    //错误一
    char myStr2[10];
    myStr1 = "Hello!";//虽然都是指针,但是定义char myStr2[10]时,为其分配的是栈内存空间,而"Hello"指向数据区中的字符常量空间,所以两者之间不能直接赋值;
    
    //错误二
    char *myStr3 = "Hello!";
    myStr3[0] = 'h'; //错误原理同上,myStr3指向的是数据区的字符常量,是不可写的内存空间,因此不能通过指针myStr3来修改;
    
  • 针对错误一的疑问:为什么 char myStr4[10] = "Hello!" 不会报错?
    myStr4的初始化,执行的是拷贝初始化,此处的等号不是简单的赋值操作,而是一个拷贝操作,也就是说右侧的"Hello!"是被拷贝到myStr4所指向的栈空间中;

2. char* 和const char*

2.1 概要
  • const关键字说明其修饰的变量不可被改变;const可以修饰变量、参数、函数、返回值等,可以提高程序的健壮性,减少程序出错(修饰函数参数(指针)时,可避免传入的参数在函数体中被修改);

  • 代码中,声明可以从右往左读,指针读成pointer to,比如:

    char * myStr: myStr is a pointer to char
    const char * myStr: myStr is a pointer to const char
    char * const myStr: myStr is a const pointer to achar

  • const char *和char const * :底层const,两者是等价的,const均修饰指针指向的内容,说明指针指向的内容为常量,不可通过该指针来修改其指向的内容;

  • char * const:顶层const,const修饰指针本身,说明指针本身是常量,表示定义的指针不可以再指向其他的地址;

2.2 C语言中处理字符的函数
  • 求字符串的长度:

    • strlen:可以用于计算字符数组中,字符的长度;也可用于计算字符指针所指向的字符串长度;

    • sizeof:用于求字符数组的长度;

      char *str1 	      = "hello!";//sizeof(str1)=8如果是32位机器,则sizeof(str1)=4; strlen(str1)=6
      const char * str2 = "hello!";//sizeof同上,求得的都是内存地址所占的字节数,strlen(str2)=6
      char str3[] 	  = "hello!";//sizeof(str3)=7, 6个字符加结尾的'\0', strlen(str3)=6
      char str4[10] 	  = "hello!";//sizeof(str4)=10 strlen(str4)=6
      

      因此,求字符串的实际长度时,经常使用strlen方法;

  • 字符串拼接和分割

    • strcat:实现两个字符串的拼接,strcat(char *dst, const char *src);

      char *str1 = "hello";
      const char *str2 = "world";
      char str3[] = "big";
      char str4[] = "eye";
      char str5[20] = "my";
      
      strcat(str1, str2);//错误,str1指向数据区的字符常量空间,不可修改,也不可拼接;
      strcat(str3, str4);//不会报错,但是拼接后的结果为"bige",这是由于str3的长度只有5个字符(包含结尾的'\0');
      strcat(str5, str2);//正确,结果为"my world"
      strcat(str5, str3);//正确,结果为"my big"
      
    • strtok:实现字符串的分割,第一个参数为待分割的字符串,第二个参数为分割符,strtok(char *src, const char* delimiter),需要注意的是,输入的src字符串应是字符数组(字符串定义在栈空间中);同strcat,输入的待分割变量应是字符数组

      char str2[] = "192.168.1.1";
      char *result = strtok(str2, ".");
      while(result != NULL){
          printf("%s\t",result);
          result = strtok(NULL, ".");
      }
      
      //输出
      192	168	1 1
      

      strtok中有一个隐含的第三个参数,每次调用strtok后,其更新为分割符后所有的字符;在上述示例代码中第一次调用strtok后,context为"168.1.1",然后如果接下来传入的字符为NULL,则strtok会对context进行分割,分割后再次更新context;源码如下:
      在这里插入图片描述
      在这里插入图片描述

  • 字符串比较

    • strcmp:逐字符比较输入的两个字符串是否相同,如果相同则返回为0,若不相同,则返回第一个不相同字符的ASCII码差值或正负1(取决于编译器),在windows下的返回情况一般是-1 0 1

      char *str1 = "Hello!"; //ASCII of 'H' is 72
      char *str2 = "hello!"; //ASCII of 'h' is 104
      int result = strcmp(str1, str2); //resut = -1 因为两者第一个字符就不相同,且'H'的ASCII码小于'h'
      
  • 字符串拷贝

    • strcpy:字符串拷贝,将一个字符串拷贝给另一个字符串,目前参数必须是字符数组(指向栈空间),不能是指向数据区的字符指针;

      char str1[] = "Hello";
      char *str2 = "Hello world!";
      strcpy(str1, str2); //执行后str1 = "Hello world!"
      

3. string

  • string是C++中的一个类,使用比较灵活,提供了很多用于处理字符串的方法;
  • 初始化:
    • std::string str1 = "Hello"; //拷贝初始化
    • std::string str2("Hello"); 或者 std::string str2(str1); //赋值初始化
    • std::string str3(const char*, n); //使用const char*中的前n个字符初始化string
    • std::string str4(n, 'A'); //使用n个字符’A’初始化字符串str4
    • std::string str5(str1, m, n); //使用字符串str1中,第m到m+n-1个字符来初始化字符串str5
  • string类中提供的方法:参考文档1 参考文档2
    • length()和size()可以返回string的有效字符串长度;
    • clear()清空字符串,empty()用于判断字符串是否为空;
    • 访问string中的第n + 1个字符:str.at(n)或者str[n];
    • swap(string s)交换两字符串的字面值;compare(string s)比较两字符串的字面值;
    • insert(),向string中插入字符,方法提供了多种重载,如insert(int p0, string s)表示从字符串的p0处,插入字符串s;
    • substr(int pos, int n)表示从pos位置处开始,截取n个字符;
    • copy(char *s, int n, int pos)表示从字符串的pos位置处,拷贝n个字符,赋值给字符数组s;

4. 各类型间的转换

4.1 char[]和char*间的转换
char str1[] = "Hello";
char *str2 = "Hi";
str2 = str1; //正确,str2本质上就是一个指针,此处相当于让指针指向栈空间中的字符串"Hello"
str1 = str2; //错误,str2指向的地址为数据区的字符常量空间,而str1指向栈空间,不能直接赋值,只能通过拷贝的方式
4.2 const char*和char*间的转换
char *str1 = "Hello";
const char *str2 = "Hi";
str2 = str1; //正确 将指针str1指向的地址赋值给
str1 = str2; //错误 不能将const int*类型的指针赋值给const int,此处同理;可以这样理解,const int *表明不能通过指针修改其指向的值,如果能够将其赋值给int *,则可以通过新的指针来修改其指向的内容了,这违背了const本身的原则;

char str3[] = "Test";
str2 = str3; //正确 并且能够通过str2来修改str3字符数组中的内容
str2[2] = 'E'; //正确
4.3 const char *、char *以及char[]间的相互转换

除第一条外,此处的结论均不包含C++中的string

  • 字符数组char[]可以作为右值,赋值给任意的字符指针(const char *、char *)或字符串(string);
  • const char* 不能作为右值进行赋值操作,除非经过指针类型的强制转化,如:char * str2 = const_cast<char *>(const char *str1);
  • char* 只能作为右值赋值给const char*
4.4 C++中的string与C中的字符串间的转换规则
  • C中的三种字符串类型均可用来对string进行赋值,此时的赋值可以理解为字符串的拷贝操作,并不会改变string变量的地址;

  • string转const char*:const char *myStr1 = myStr2.c_str();其中myStr2为string类型;

  • string转char *:使用上述的方式只能转换到const char *,如果需要将sring转换成char *,可以调用上述的copy方法,如:myStr2.copy(myStr3, myStr2.length() + 1, 0);,其中myStr2是string类型的字符串,myStr3是char *类型的字符串,加一是因为字符串结尾的’\0’;

  • string转char[]:使用strcpy函数实现拷贝赋值,strncpy(myStr4, myStr2.c_str(), myStr2.length() + 1);,任何类型的字符串转char[]都可以使用strcpy拷贝赋值方法;

  • char *转int:使用atoi函数(atoi(char * x)),类似的函数还有,atof(char *转float)、atol(char *转long);如果是单个字符,还可以通过int a = s - '0';实现,其中s为单个字符char;

  • int转char *:使用_itoa或者sprintf函数;_itoa的用法为_itoa(a, s, int base);,其中a为int类型,s为char *类型,base表示a的进制类型(10进制、8进制、16进制);sprintf的用法为sprintf(s, "%d", a);
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值