字符串操作总结(转)

概述

对个字符串的函数的解释根据的是C语言标准文档
<<INTERNATIONAL  ISO/IEC STANDARD 9899>>,
完全符合各注意事项可确保您的程序安全无恙,否则您的程序可能会有时段错误,有时不段错误,有时当机,有时不当机.



定义

字符串

字符串是以null结束的字符的序列,它包括第一个null字符,但不包括从第一个null之后的字符

指向字符串的指针

指向字符串的指针是,指向字符串第一字符的指针(低地址)

字符串的长度

null字符之前的所有字符的总数,不把null算在内<o:p></o:p>

“123”的长度是3

字符串的结束位置

指的是\0所在的位置

字符串操作

\0结束系列

strlen

原型:size_t strlen(const char *s);

功能:算字符串长度,不包括\0

注意事项:

1        
指针s 必须合法

2        
s所指字符串必须以\0结束

3        
所返回的长度是不把结束符号\0算在内的

病例分析<o:p></o:p>

1 产品缺陷分析报告.doc 缺陷11
违反了注意事项3,错误的认为strlen
算出的长度包括\0<o:p></o:p>

<o:p> </o:p>

strchr<o:p></o:p>

原型<o:p></o:p>

#include <string.h>

char strchr(const char s, int c);

描述<o:p></o:p>

The strchr function locates the first

occurrence of c (converted to a char)in the

string pointed to by s. The terminating

null character is considered to be part of the

string.

返回值<o:p></o:p>

The strchr function returns a pointer to the

located character, or a null pointer if the

character does not occur in the string.

函数strchr 返回的指针指向c所在位置.如果c不在字符串s中出现则返回空指针

注意事项<o:p></o:p>

1 指针s必须合法

2 s所指字符串必须以\0结束

3 结束符号\0也参与了搜索,即可以将参数c赋为0,此时返回值将指向s的结束位置

<st1:chmetcnv unitname=”C” sourcevalue=”4” hasspace=”True” negative=”False” numbertype=”1” tcsc=”0” w:st=”on”>4 c</st1:chmetcnv>的取值范围必须是-128127,如果是其它值,行为是未定义的

<o:p> </o:p>

strrchr 

原型<o:p></o:p>

 #include <string.h>

char strrchr(const char s, int c);

描述<o:p></o:p>

The strrchr function locates the last

occurrence of c (converted to a char)inthe

string pointed to by s. The terminating

null character is considered to be part of the

string.

返回值<o:p></o:p>

3 The strrchr function returns a pointer to

the character, or a null pointer if c does not

occur in the string.

注意事项<o:p></o:p>

跟函数 strchr 一样,不同之处,只是它从后往前搜索<o:p></o:p>

<st1:chsdate year=”1899” month=”12” day=”30” islunardate=”False” isrocdate=”False” w:st=”on”>7.21.5</st1:chsdate>.7 The strstr function<o:p></o:p>

原型<o:p></o:p>

#include

<string.h><o:p></o:p>

char

strstr(const char s1, const char *s2);<o:p></o:p>

描述<o:p></o:p>

The

strstr function locates the first occurrence in the string pointed to by s1 of

the<o:p></o:p>

sequence

of characters (excluding the terminating null character) in the string pointed

to<o:p></o:p>

by s2.<o:p></o:p>

返回值<o:p></o:p>

The

strstr function returns a pointer to the located string, or a null pointer if

the string<o:p></o:p>

is not

found. If s2  points to a string with

zero length, the function returns s1.<o:p></o:p>

注意事项<o:p></o:p>

1 指针s1合法,指针s2合法<o:p></o:p>

2 s1必须以\0 结束,s2必须以\0结束<o:p></o:p>

3 如果s2所指字符串长度为0,则返回s1<o:p></o:p>

4 如果找不到s2所指字符串,则返回NULL<o:p></o:p>

<o:p> </o:p>

病例分析<o:p></o:p>

1 产品缺陷分析报告.doc 缺陷2
违反了 注意事项 2<o:p></o:p>

<o:p> </o:p>

strcpy

原型<o:p></o:p>

#include <string.h>

char strcpy(char s1,

const char * s2);

Description<o:p></o:p>

The strcpy function

copies the string pointed to by s2 (including the terminating null<o:p></o:p>

character) into the

array pointed to by s1. If copying takes place between objects that<o:p></o:p>

overlap, the behavior is

undefined.<o:p></o:p>

Returns<o:p></o:p>

The  strcpy function returns the value of s1.<o:p></o:p>

返回s1

注意事项<o:p></o:p>

1 s2所指字符串必须以\0结束

2 s1所指缓冲区间长度需>= strlen(s2)+1

3  s2所指前strlen(s2)+1个字节,不能s1所指的前 strlen(s2)+1个字节有重叠,否则行为是未定义的

strcat

原型

#include <string.h>

char strcat(char s1,

const char * s2);

描述

The strcat function appends a copy of the

string pointed to by s2 (including the

terminating null character) to the end of

the string pointed to by s1. The initial character

of s2 overwrites the null character at the

end of s1. If copying takes place between

objects that overlap, the behavior is

undefined.

Thestrcat function returns the value of s1.

注意事项:

1 指针
s1合法, s2合法

2 s1\0结束,s2\0结束

strcmp

原型<o:p></o:p>

#include <string.h>

int strcmp(const char s1, const char s2);

描述<o:p></o:p>

The strcmp function compares the string

pointed to by s1 to the string pointed to by

s2.

返回值<o:p></o:p>

The strcmp function returns an integer

greater than, equal to, or less than zero,

accordingly as the string pointed to by s1

is greater than, equal to, or less than the string

pointed to by s2.

注意事项<o:p></o:p>

1s1 必须以\0结束

2 s2 必须以\0结束

3 如果s1 长度小于s2长度,s2中只有前strlen(s1)+1个字符对结果有影响

4如果s2 长度小于s1长度,s1中只有前strlen(s2)+1个字符对结果有影响

5 比较两个字符是按无符号数比较的

<o:p> </o:p>

strn…系列

strncpy

原型

#include <string.h>

char strncpy(char restrict s1,

const char * restrict s2,

size_t n);

描述

The strncpy function copies not more than n

characters (characters that follow a null

character are not copied) from the array  pointed to by s2 to the array pointed to by

s1. If copying takes place between objects

that overlap, the behavior is undefined.

If the array pointed to by s2 is a string

that is shorter than n characters, null characters

are appended to the copy in the array

pointed to by s1, until n characters in all have been

written.

<o:p> </o:p>

返回值

The strncpy function returns the value of

s1.

<o:p> </o:p>

注意事项<o:p></o:p>

1 s1 所指的前n个字节是已分配的内存,

2 s2 必须以\0结束, 或者从s2开始的前n个字节都是已分配的内存.

3

  如果s2 \0结束,s2所指的前 strlen(s2)+1个字节不能 s1所指的前n个字节重叠

  如果s2不以\0结束,则则s2所指的前n个字节不能 s1所指的前n个字节重叠

4

如果s2所指的前n个字节不含 \0,则经过拷贝后s1不以\0 结束.

病例分析<o:p></o:p>

病例1

int main()

{

   char

src[]=”123”;<o:p></o:p>

char dst[4];<o:p></o:p>

strncpy(dst,src,8);<o:p></o:p>

return 0;<o:p></o:p>

}

违反了注意事项1,此代码在应用层会内存出错,但在内核不会出错.因为C库遵守了ISO C标准,会拷贝够8个字符(通过补若干个\0),LINUX内核的代码出于对效率的考虑,只拷贝了4个字符.<o:p></o:p>

<o:p> </o:p>

病例2

int main()

{

char src[]=”<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”123” unitname=””” w:st=”on”>123”;

strncpy(src,src,4);

return 0;

}

违反了注意事项2,行为是未定义的,在某些编译器下会出错,某些编译器下不会出错.<o:p></o:p>

病例3

int main()

{

  char src[]=”<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”12345” unitname=””” w:st=”on”>12345”;

  
char buf[6];

  
strncpy(buf,src,5);

  
printf(“%d\n”,strlen(buf); //(1)
在此当机

return 0;

}

违反了注意事项4,buf 不以\0结束.(1)中当机,此错误因在调用strncpy时不出错,在后续代码中才出错,非常难查.<o:p></o:p>

<o:p> </o:p>

strncat

原型<o:p></o:p>

#include <string.h>

char strncat(char restrict s1,

const char * restrict s2,

size_t n);

描述<o:p></o:p>

The strncat function appends not more than

n characters (a null character and

characters that follow it are not appended)

from the array pointed to by s2 to the end of

the string pointed to by s1. The initial

character of s2 overwrites the null character at the

end of s1. If copying  takes place between objects that overlap, the

behavior is undefined.

. A terminating null character is always

appended to the result.

<o:p> </o:p>

返回值<o:p></o:p>

The strncatfunction returns the value of

s1.

注意事项<o:p></o:p>

1 s1 所指缓冲区间必须>= strlen(s1)+n+1个字节

2 拷贝的结果始终以\0结束,这点跟strncpy是不一样的

<o:p> </o:p>

病例分析:

int main()

{

  char  str1[]=”<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”123” unitname=””” w:st=”on”>123”;

 
char str2[]=”abcd”;

  int

len1;

  int

len2;

  int

len;

 
char * obj;

<o:p> </o:p>

 
len1 = strlen(str1);

 
len2 = strlen(str2)

  len

=len1 +len2;

  obj  = malloc(len);

strcpy(obj,str1);

#if   0

strncpy(obj+len1,str2,len2);

#else

strncat(obj, str2,strlen(s2));

#endif

return 0;

}

<o:p> </o:p>

说明: #else …

#endif
之间的代码将导致内存出错,

obj
至少要len+1个字节.

#if 0 
… #else
之间的代码不会出现内存错误,但为后续代码埋藏了隐患,因为obj

\0结束符.

strncmp

原型<o:p></o:p>

#include <string.h>

int strncmp(const char s1, const char s2,

size_t n);

描述<o:p></o:p>

The strncmp function compares not more than

n characters (characters that follow a

null character are not compared) from the

array pointed to by s1 to the array pointed to

by  s2.

返回值

The strncmp function returns an integer

greater than, equal to, or less than zero,

accordingly as the possibly null-terminated

array pointed to by s1 is greater than, equal

to, or less than the possibly

null-terminated array pointed to by s2.

注意事项

1 s1 长度>=n

2 s2长度>=n

3 返回值的符号以比较过程中第一对不相等的字符为准.假设第一对不相等的字符为a,b

如果a>b 返回的是正数,否则是负数.如果整个比较过程没发现不相等的字符对,则返回0.

4 s1,s2 从第n+1个字符开始的字符(如果存在的话)对比较结果无影响

5 n>=0

<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”True” sourcevalue=”6” unitname=”C” w:st=”on”>6 C</st1:chmetcnv>标准明确规定在比较过程中,将每个字符解释为unsigned

char

实例分析<o:p></o:p>

实例一

strncmp(“<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”123” unitname=””” w:st=”on”>123”,”<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”1234” unitname=””” w:st=”on”>1234”,3)
返回值为0

strncmp(“<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”123” unitname=””” w:st=”on”>123”,”<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”1234” unitname=””” w:st=”on”>1234”,4)
返回值<0

strncmp(“<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”123” unitname=””” w:st=”on”>123”,”<st1:chmetcnv tcsc=”0” numbertype=”1” negative=”False” hasspace=”False” sourcevalue=”1234” unitname=””” w:st=”on”>1234”,5)内存出错

实例二

include <stdio.h>

#include <string.h>

int main()

{

       char

src[]=”123”;

       char

obj[256]={‘1’,’2’,’3’,-1};

       int

ret;

       ret

= strcmp(obj,src);

       printf(“%d\n”,ret);

<o:p> </o:p>

       return

0;

<o:p> </o:p>

}VC gcc的测试结果都是输出1,C标准解释结果应该是>0

总结

1 不要人为的假设一个字符串一定是以\0结束的,特别是对网络中的数据包.

2在无校验码的情况下,不建议在网络传输一个以\0结束的字符串.因为传输过成会出错

3如果要传\0结束的字符串给驱动,建议实现驱动的ioctl时在传入参数时加上magic number,确保此参数来自你的应用程序.

4strncpy的执行结果不一定
含有\0,strncat的结果一定含有0

5 在调用拷贝函数strcp strncpy 连接函数strcat strncat 确保你分配的缓冲区间足够大

0%