C++字符串分析

字符串


字符串在百度PS的地位自然不必多说,如果你有代码权限的话,在检索端任意模块的源码中strcpy就知道了。从用户输入的一个query分析、0个字符组成,也就是空串,千万不要小瞧空串,很多程序c++中的StringBuffer类。所有变长字符串还是在长度上有个极限,一般的说这个极限只依赖于可获得的内存的数量。

定义中并没有限定字符串的表示法和组织形式,虽然通常 NUL ( 0 )为结束符,而组织形式通常是以字符数组的形式。但是并不排除其他的组织形式存在,例如, java 中的 c_str ()或 Pascal 语言的组织更是诡异:以一个 整数 值开头来表示整个字符串的长度,而没有任何结束符标志,大家坐公交车时也可以想一想这种组织方法有哪些弊端,反正我只知道 c的争宠,J。当然,可能还有其它的表示法,使用 列表 可以使得一些字符串操作(如插入和删除)更高效,这里就不多加讨论了,后面讨论的都是“正常”的字符串,即以’ 1 个 ascII 编码字符,但是有些 意音文字 的语言比如 汉语日语朝鲜语 CJK 256 个字符 ) ,由此产生的编码方式真是五花八门,足够写一本史记, 16 位编码方式。 各种针对字符串操作的库可能随着 , 它既具有普通数组的一般性质 '\0', 标志字符串的结束。字符串变量是以 : 一是当作字符的数组来使用。这时的用法与整数的数组、实数的数组等相同,对字符数组的输入、输出、赋值、引用等都是针对单个的元素进行。二是更为重要的用法即存储、处理字符串。这时它除了可以像普通数组一样使用外,还可以把字符串作为一个整体进行操作。

对字符数组的初始化有两种方式。一种是用字符常量进行初始化,另一种是用字符串常量进行初始化。用单引号字符常量放在大括号中初始化字符数组需要一个一个的指定,够笨、工作量也比较大,J;用字符串常量初始化一个字符数组时如果字符串常量长度小于数组长度,则只将这些字符赋绐数组中前面的元素,其余元素自动定为空字符'\0'),够方便,但是要注意系统会在字符数组的末尾自动加上一个字符1,比如:

char str[5]="HELLO";

在编译时是会失败的,并无大碍,但是有时程序中暂时不能确定字符数组的初始值,需要先定义数组空间,再进行赋值,代码如下:

char str[5];

strcpy(str,"hello");

这次编译器就形同虚设了,str后面的内存被写越界,会引发大问题并很难追查。


存储区的差异

字符串初始化另一个需要特殊关注的点是不同存储区有不同的初始值,其实这个不是字符串数组特有的,全局变量和静态变量,不管是数组还是简单变量还是复合变量,都默认全部置vc6.0的人还记得变量查看窗口中显示的字符数组“烫烫烫烫烫烫烫。。。”吧,随机数char型数组加结束符,因此可以像操作数组那样自由操作字符串,可以充分发挥&(取地址)运算符来找到字符串中某个字符的内存地址;也可以通过对指向某个字符串的指针使用++、再取值、值printf("%s",str);函数时,每输出一个字符检查一次,看下一个字符是否'\0'就停止输出。


字符串的输入输出


字符串的输入


scanf函数

用带%s格式符的scanf函数读入的字符串开始于第一个非空白符,包括下一个空白符\0'。例:输入:str的只有"world"被留在输入缓冲区中等待下一次输入函数的读入。

二是要保证字符数组的长度足够大

char t[5],s[10];

scanf("%s",t);

dingdong

则字符串t的空间s的空间。


gets函数

gets(字符数组名,函数参数<FONT face=""">"字符数组名<FONT face=""">"规定了只能使用数组名而不能是字符串常量。与gets函数将用户键入的换行符之前的所有字符'\t'和,然后加上scanf函数相同的是


字符串输出


printf函数

用带printf函数能进行字符串的输出。存放在字符数组中的字符串被全部输出,直至遇到


puts函数

);

其中,参数<FONT face=""">"字符串<FONT face=""">"可以是字符串常量puts函数打印字符串的全部内容'\0'为止,然后自动多打印一个printf函数无此功能。scanf和gets和scanf和gets和


基本字符串处理函数介绍

介绍最有用又最常见的四个字符串处理函数:strcat、strcpy。这些函数的原型存放在#include命令包含


strlen函数

'\0')length=strlen(字符串)

例:3。""长度为,所以长度为


strcat函数

1,字符串strcat函数把字符串1的后面。其中,参数“字符串<FONT face=""">1"必须是字符串变量,而<FONT face=""">"字符串<FONT face=""">2"则可以是字符串常量或变量。strcat函数后,'\0'取消,只在新串最后保留一个strcat函数不检查字符串2。如果没有足够的空间,多余的字符将溢出至邻近的内存单元,破坏这些单元原来的内容。所以连结前应调用'\0'留一个位置。


strcmp函数

,返回比较的结果。一般形式是:rtn=strcmp(s1,s1、rtn是用于存放比较结果的整型变量。比较结果是这样规定的:s1小于strcmp函数返回一个负值;

②s2,s1大于strcmp函数返回一个正值;

字符串大小的比较是以strcmp()首先将s2第一个字符值,若差值为0则将差值返回。


strcpy函数

1,字符串,字符串,而不能是字符串常量。2的内容完全复制到字符串,而不管字符串2保持不变。,由于字符串是数组类型

*/

*/

除此之外,还有很多关于字符串的库函数,比如字符测试、字符串转换以及更复杂的字符串操作,请参见1、strlen

如果您的代码中充分考虑了程序未来的可维护性和扩展性,那么就对下面代码中的strlen不会陌生,请看下面的代码:

while(fgets(Buffer, sizeof(Buffer), fp) != NULL)

{

if (Buffer[0] != '\0' &&Buffer[strlen(Buffer)-1] != '\n')

{

ul_writelog(UL_LOG_WARNING, "line is toolong", file);

}

}

是否对strlen的使用非常清楚呢?这段代码的意思是从Buffer缓冲区长度,然后判断读取到的字符串是否非空以及末尾是否以换行结束,非空并且没有换行符则说明行超长,打印日志。首先,strlen是库函数;再者,strlen只判断结尾符之前的字符个数(不包括结尾符),两者有根本的区别,而且大多数情况下计算出来的值并不相等。

一个容易犯错的例子如下:需求时发送一个字符串给对端,但是不发送最后的

char str[] = "hello";

if ((len =send(socket_descriptor,str,sizeof(str),0)) == -1)

{

perror("Error in send\n");

exit(1);

}

发送sizeof(str)为5,错用了strlen(str)取字符串的长度。

另外,sizeof(str)和2、提防魔鬼数字

一些库函数,比如strncpy、strncpy(目的字符串,13);

那么想必谁都很头疼“13”就会出问题,而这种问题的追查也是破费心机的,因为要想定位这种改动代码对以往代码的影响的sizeof、review时一起捉鬼!


strlen函数的计算值错误,strncpy,如果源字符串长度大于指定的长度,那么最后字符串也会缺少fread以二进制的方式将文件载入内存,不会在未尾加fread之后主动为文本的末尾加上4、目的地址空间是否足够大

正如前面所说的,一些库函数的设计者假定程序员都是谨慎的,把诸如检查目的内存是否足够放下源字符串的任务推给了程序员,比如strcat函数,如果参数(buffer Overflow)的错误情况,在编写程序时请特别留意,或者用strcpy、memcpy实际拷贝之前就对字符串和目的内存长度作检查,而不是在拷贝之后做,因为那时缓冲区溢出可能已经发生了,当然,合法性检查肯定会带来效率的损失,这是需要衡量的,一定可以保证没有问题的话就不必做了。


strchr(查找字符串中第一个出现的指定字符),如果找到指定的字符则返回该字符所在地址,否则返回strchr返回" p="" style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Times New Roman'; FONT-SIZE: 10.5pt" lang="en-US" if="" index="" p="" p="" style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Times New Roman'; FONT-SIZE: 10.5pt" lang="en-US" strncpy="" name="" grepstr="" index-grepstr-1="" p="" p="" style="MARGIN: 0in 0in 0in 0.375in; FONT-FAMILY: 'Times New Roman'; FONT-SIZE: 10.5pt" lang="en-US" p="" p="" style="MARGIN: 0in 0in 0in 0.375in; FONT-SIZE: 10.5pt" font="" face="宋体" font="" font="" face="">stl容器pop和6、是否负越界

绝大多数内存越界都是正越界,即写过了;其实还有一种越界是写到前面去了,因为不容易发生,所以更难追查,问题代码如下:

在使用str中只包含了len<0的情况,导致越界。

后续还会分析这些问题的测试方法,是否能用<FONT face=""">pclint来检查出来,想想吧,如果不用运行代码就可以检查出这些问题是件多么激动人心的事情!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值