9.1 字符串基础
1、除了字符串常量,其它字符串都必须存储于字符数组或者动态分配的内存中。
2、字符串的长度并不包括NUL字节,就是它包括的字符串的个数。
3、头文件<string.h>包括了使用字符串函数所需的原型和声明。
4、库函数strlen的原型如下:size_t strlen( char const *string ); 。size_t类型是在头文件<stddef.h>中定义的,是一个无符号整数。
注: 如果表达式中同时包括有符号数和无符号数,那么会产生奇怪的结果,按需求类型强制转换。
9.2 不受限制的字符串函数
9.2.1 复制字符串 和 连接字符串
两个原型分别为:
1、char *strcpy( char *dst, char const *src );
2、char *strcat( char *dst, char const *src );
这两个函数的返回值都是第一个参数的副本。因此可以这种写法:strcat( strcpy( dst, a ), b);
dst必须是字符数组或者一个只想动态分配内存的数组指针。
在使用这两个函数时,确保dst数组空间足以保存整个字符串。
9.2.2 字符串比较
原型:int strcmp ( char const *s1, char const *s2 );
如果 s1 < s2 ,返回一个小于0的值;如果 s2 > s2 ,返回一个大于0的值;两者等于就返回0。
字符串大小比较:
两个字符串逐个字符进行比较,直到发现不匹配位置,此时在字符集中字符序数小的字符串小。如果一个字符串是另一个字符串的一部分,则前者小于后者。
9.3 长度受限的字符串函数
三个原型分别为:
1、char *strncpy( char *dst, char const *src, size_t len );
2、char *strncat( char *dst, char const *src, size_t len);
3、int strncmp( char const *s1, char const *s2, size_t len);
注意1: 在使用strncpy时,如果src的长度小于Len,那么会在后面自动补充NUL字节。如果src的长度大于len,那么dst结尾就没有NUL字节,这是错误的。
注意2: strncat,即使src的长度 大于len也会尽可能连接最后加上NUL。
注意3: strncmp,只比较len长度字节。
9.4 字符串查找的基础
9.4.1 查找字符
几种函数的原型分别如下:
1、char *strchr( char const *str, int ch );
查找ch 在str中第一次出现的位置,返回该位置的指针,没找到返回NULL指针。
2、char *strrchr( char const *str, int ch);
查找ch 在str中最后一次出现的位置,返回该位置的指针,没找到返回NULL指针。
3、char *strpbrk( char const *str, char const * group );
返回指向str中第一个匹配group中任何一个字符的字符位置。
9.4.2 查找一个子串
原型:char * strstr( char const *s1, char const *s2 );
返回s2在s1中第一次出现的位置,没出现就返回 NULL指针。s2为空,则返回s1。
9.5 高级字符串查找
9.5.1 查找1个字符串前缀
原型:
1.size_t strspn( char const *str, char const *group );
2.size_t strcspn( char const *str, char const *group );
9.5.2 查找标记
原型:char *strtok( char *str, char const *sep );
9.6 错误信息
当调用一个函数,请求操作系统执行一些功能,如果出现错误,操作系统是通过设置一个外部的的整型变量errno进行错误代码报告。strerror函数把其中一个错误代码作为参数并返回一个用于描述错误的字符串的指针。
函数原型:char *strerror( int error_number );
9.7 字符操作
标准库包含了两组函数用于操作单独的字符,他们的原型位于头文件**<ctype.h>**。一组用于字符分类,一组用于转换字符。
9.7.1 字符分类
函数 | 满足条件则该函数返回真 |
---|
iscntrl | 如果是任何控制字符 | isspace | 空白字符:空格’ ’ , 换页’\f’ , 换行’\n’ , 回车’\r’ , 制表符’\t’ , 垂直制表符’\v’ | isdigit | 十进制数字:0~9 | isxdigit | 十六进行数字:09,af , A~F | islower | 小写字母:a~z | isupper | 大写字母:A~Z | isalpha | 字母:a~z 或 A~Z | isalnum | 字母(isalpha)或十进制数字(isdigit) | ispunct | 表达符号,任何不属于数字或者字母的图形符号(可打印的符号) | isgraph | 任何图形符号 | isprint | 任何可打印符号,包括图形字符和空白字符 |
9.7.2 字符转换
转化字符可以把大写字母改为小写,小写字母改为大写。如果传递给函数的参数不是要求的大小写字母,那么就返回原参数,不做修改。
函数原型分别为:
1、int tolower( int ch ); //把大写字母改为小写
2、int toupper( int ch ); //小写字母改为大写
注意: 自己编写程序测试操作字符会降低程序的可移植性。
例如:if ( isupper( ch ) ) 可以在任何机器上运行
然而 if( ch >= 'A' && ch <= 'Z' ) 只能在使用ASCII字符码的机器上运行。
9.8 内存操作
由于字符穿的定义是以NUL字节结尾,所以NUL不能出现在字符串中间。但是非字符串数据内部包含NUL的情况不少,无法使用字符串的函数来处理非字符串的数据。此时有另外一组相关的函数,这些函数可以处理任意的字节序列,它们在遇到NUL字节不会停下。他们的函数原型如下:
void *memcpy( void *dst, void const *src, size_t length );
void *memmove( void *dst, void const *src, size_t length );
void *memcmp( void const *a, void const *b, size_t length );
void *memchr( void const *a, int ch, size_t length );
void *memset( void *a, int ch, size_t length );
char a[size],b[size];
...
memcpy( b, a, size );
int c[size],d[size];
...
memcpy( c, d, sizeof(d) );
memcpy( c, d, size * sizeof(d[0]) );
memmove( x, x + 1, ( size - 1 ) * sizeof( x[0] ) );
|