20140917 C++学习之字符串

摘要:

本文试着比较c++字符串与C风格字符串,主要讨论的是c++中的字符串的简单操作。

1、C风格字符串的主要操作与缺陷;

主要操作有: strlen (求长度)、strcpy(复制字符串) 、strcmp(比较字符串大小)、strcat(字符串连接)、strstr(寻找子字符串)

C标准库实现:

char str1[20] = "hello"; //必须有足够大的容量。

char str2[6] = "world!";

1)、strcat

str1 = strcat (str1 ,str2);//将str1末尾的 ‘ \0 ‘用str2 中的 ‘ w ‘替换 。并在新的 str1 末尾自动添加 ’ \0 ‘ 。

               //strcat函数返回的是 新的str1 的首地址

2)、strlen //统计字符串中字符的个数 ,而不将 ‘ \0 ’计入

strlen(str2) = 6 ;

sizeof(str2) = 7 ;

C风格字符串缺陷:

1)、结束符 ‘ \ 0 ‘;

2)、很多时候需要自行保证安全性,例如下面的代码很容易让程序崩溃

#include<iostream>
#include<string.h>
using namespace std ;

int main(int argc ,char *argv[])
{
	char buf[3] ;

	strcpy(buf ,"hello");

	cout << buf << endl ;
}

这里错误的原因在于buf 的内存不够 ,产生内存越界,但是 strcpy 不会也无法检测内存是否越界。

C++ 的解决方案是引入了string类型,我们稍后叙述。

这里再叙述很多同学在自己实现字符串的一系列函数中出现的错误以及原因,代码如下;

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std ;
 4
 5 char *strcat(char *s1 ,const char* s2)
 6 {
 7         s1 = (char*)malloc( strlen(s1) + strlen(s2) );
 8 }
 9
10 char* strcppy(char*s1 , const char* s2)
11 {
12         s1 = (char*)malloc( strlen(s2) );
13 }
14
15 int main(int argc ,char *argv[])
16 {
17     char p[128] ;
18
19     strcat( p ,"hello");
20
21     return 0 ;
22 }

上述代码的错误之处:

1)、我们姑且不管malloc分配内存的大小(当然此处分配的大小肯定是不够的)。

首先对 s1进行重新分配内存显然是无效的,当main函数执行到strcat时 ,会调用strcat函数,然而在strcat函数中 s1 的任何改动都与 p 无关 。因为我们知道C语言中的 参数传递 是 值拷贝(以后会详细叙述)。这实际上造成了内存泄露。

2)、就算这里能够改变 p 的指向,这样的做法也是不允许的。因为这会使得其他地方的字符串失效。当然这里不太可能。不做额外讨论。

2、C++字符串的实现

相对于C,C++提供了一种类型 string,可以更加简单更加安全的操作字符串。代码如下:

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

int main(int argc ,char*argv[])
{
    string s1 = "hello ";
    string s2("test"); //赋值
    string s3 ; //空字符串

    cout << s1 << endl ; //打印
    cout << s1,size() << endl ;//求长度
    s3 = s1 ;//字符串的复制

    s3 += s2 ;//OK!字符串的拼接strcat
    s3 = "hello" + "world" + s1 ; // error 右结合性 char*和char* 不可相加
    s3 = s1 + "hello " + "world" ; //ok 右结合性 ,先计算s1+“hello”生成新的str

    cout << s3 << endl ;

    //比较大小
    cout << (s1 > s2) << endl ;
    cout << (s1 == s3) << endl ;
    return 0 ;
}

string 同样支持下标操作 和 迭代器操作(可以理解成指针 ,以后详细叙述),代码如下:

//下标操作
	for(size_t ix = 0 ;ix != s.size() ; ++ ix)
	{
		cout << s[ix] << " "  ;
	}
	cout << endl ;
//迭代器操作
for (string::iterator it = s3.begin() ;//指向容器的第一个位置
   it != s3.end(); // 指向容器最后一个元素的下一个位置     it++ )
{
	cout << *it << " " ;
}
cout << endl ;

一下代码实现的是字符串的查找(查找单词的情况与此一样 ,我们就不再赘述):

//查找单个字符

int main(int argc ,char *argv[])
{
	string str ;

	getline(cin ,str); // 读入字符串 ,遇见空格或者enter键表示输入结束

	char ch ;
	while(cin >> ch)
	{
		string::size_type pos = s.find(ch) ;
		if( pos != string::npos )//search success
		{
			cout << pos << endl ;// 下标
		}else 	 // false
		{
			cout << "find failure!" << endl ;
		}
	}
       return 0 ;
}

最后 ,string 可以转化为C风格字符串:

//转化为C风格字符串

string s = "shenzhen" ;

cout << s.c_str() << endl ;

注意:

1)、string 得出的 char* 是const(只读)属性 ,不可对其修改 ;

2)、另外,这个值可能失效,所以,如果需要,最好每次调用 s.c_str() ;

时间: 2024-10-12 18:05:21

20140917 C++学习之字符串的相关文章

python学习之 字符串前&#39;r&#39;的用法

python学习之 字符串前'r'的用法 在打开文件的时候open(r'c:\....') 加r和不加''r是有区别的 'r'是防止字符转义的 如果路径中出现'\t'的话 不加r的话\t就会被转义 而加了'r'之后'\t'就能保留原有的样子 在字符串赋值的时候 前面加'r'可以防止字符串在时候的时候不被转义 原理是在转义字符前加'\' 例: s=r'\tt' print(s) Output: '\tt' s='\tt' print(s) Output: '        t' python学习之

java学习-关于字符串String

有必要总结记录一下java的学习,否则,永远只是记忆碎片化和always google(费时) 刚好,小伙伴给了一份自己做的review,在学习的过程中,update一下自己的见解和学习内容: 关于String: 1 package string_keywords; 2 /** 3 * 参考url: http://developer.51cto.com/art/201106/266454.htm 4 * 5 * 常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.cla

Redis源码学习:字符串

Redis源码学习:字符串 1.初识SDS 1.1 SDS定义 Redis定义了一个叫做sdshdr(SDS or simple dynamic string)的数据结构.SDS不仅用于 保存字符串,还用来当做缓冲区,例如AOF缓冲区或输入缓冲区等.如下所示,整数len和free分别表示buf数组中已使用的长度和剩余可用的长度,buf是一个原生C字符串,以\0结尾. sds就是sdshdr中char buf[]的别名,后面能看到,各种操作函数的入参和返回值都是sds而非sdshdr.那sdshd

《python基础教程(第二版)》学习笔记 字符串(第3章)

<python基础教程(第二版)>学习笔记 字符串(第3章)所有的基本的序列操作(索引,分片,乘法,判断成员资格,求长度,求最大最小值)对字符串也适用.字符串是不可以改变的:%左侧是格式字符串,右侧是需要格式化的值print '%s=%d' % ('x',100) ==> x=100%% 格式字符串中出现 %模板字符串:from string import Templates=Template('$x is 100');  s.substitute(x='ABC');  ==> '

R语言学习(5)-字符串和因子

字符串和因子 1.字符串 创建字符串 > c("HELLO","WORLD") [1] "HELLO" "WORLD" 使用paste函数连接字符串 > paste(c("hello","hi"),"world") [1] "hello world" "hi world" > paste(c("hel

python3学习之字符串

s='this is test message' s.capitalize()    首字母大写,其它小写 s.find(sub[, start[, end]])      在指定范围内(默认全部字符串),查找sub是否包含在字符串中,包含时                                             返回第一次匹配的index,否则返回-1 s.rfind(sub[, start[, end]])    在指定范围内(默认全部字符串),查找sub是否包含在字符串中,

程序员编程技术学习笔记——字符串包含

程序员编程技术学习笔记--字符串包含 1.题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都在字符串A里?为了简单起见,我们规定输入的字符串只包含大写英文字母,请实现函数boolStringContains(string &A, string &B) 比如,如果是下面两个字符串: String 1:ABCD String 2:BAD 答案是true,即String2里的字母在String1里也都有,或者说Strin

golang学习笔记————字符串

字符串的创建 在golang中 字符串是使用双引号("")包裹住的字符序列: 字符是使用单引号('')包裹住的单一字符: 声明字符串的方式:var strvalue string 声明并创建的方式:strvalue := "This is a string!"; KeyPoint: 一旦字符串变量被初始化后,则不可单独改变该字符串序列中的某一字符:但该字符串变量可以重新被赋值: Ex:   strvalue := "abcd" fmt.Print

Java学习笔记--字符串和文件IO

1.Java中的字符串类和字符的表示 2.区分String,StringBuilder和StringBuffer 3.从命令行中给main方法传递参数 4.文件操作 1 Java中的字符串和字符 1.1 String类 字符串就是由一系列的字符组成的序列,在很多语言中,比如C语言,将其存储在一个数组中.现在运用Java的思想,就要将字符串视为一个对象,其中Java规定的String类有11个构造方法,同时还有至少40种实现的方法,通过String类的学习,可以很好地了解面向对象的类和对象的思想.