字符串基本操作
字符串就是一串零个或多个字符,并且以一个位模式为全0的NULL字节结尾,因此,字符串所包含的字符内部不能出现NULL,NULL是字符串的终止符,但并不是字符串的一部分,所以字符串的长度不包含NULL。
给字符串赋初值
void *memset(void *s, int c, size_t n);
memset函数把s所指的内存地址开始的n个字节都填充为c的值。
例如使用malloc分配的内存初值是不确定的,常用用memset清零。
取字符串长度
size_t strlen( const char );
size_t是一个无符号整型,是这样定义的 typedef unsigned int size_t; 既然它返回的不是整型数,那么如果你想直接对他的表达式进行操作,那么肯定就会存在一些问题,如下:
if( strlen(str1) - strlen(str2) >=0 )
这个判断语句将永远都是真的,因为左侧的是无符号数,那个不可能比零小,所以这样做就和你的预期想法完全不同了。所以对 strlen 的返还值进行强制转换为 int 类型就不用担心这种问题的出现。
拷贝字符串
strcpy
char * strcpy( char *dst, char const *src);
函数的功能是把 src 字符串复制到 dst ,如果两参数在内存中出现重叠,那么结果是未定义的。
因为 dst 将被修改所以他不可以是字符串常量,这个函数有一个返还值,这个返还值其实就是操作后的字符串指针的一个复制。
strcpy在拷贝字符串时会把结尾的'\0'也拷到dest中,因此保证了dest中是以'\0'结尾的字符串。
strcpy只知道src字符串的首地址,不知道长度,它会一直拷贝到'\0'为止,所以dest所指向的内存空间要足够大,否则有可能写越界。
src和dest所指向的内存空间不能有重叠 ,即不能出现下面形式的代码:
char buf[10] = "hello";
strcpy(buf, buf+1);
strncpy
char * strncpy( char *dst, char const *src, size_t len );
strncpy的参数n指定最多从src中拷贝n个字节到dest中,换句话说,如果拷贝到'\0'就结束,如果拷贝到n个字节还没有碰到'\0',那么也结束,调用者负责提供适当的n值,以确保读写不会越界 。
但是同时也意味着dest有可能不是以'\0'结尾的,为了确保dest是以 '\0'结尾的,可以添加下面形式的代码:
char buf[10];
strncpy(buf, "hello world", sizeof(buf));
buf[sizeof(buf)-1] = '\0';
如果src字符串全部拷完了不足n个字节,那么还差多少个字节就补多少个'\0' 。
memcpy
void *memcpy(void *dest, const void *src, size_t n);
memcpy函数从src所指的内存地址拷贝n个字节到dest所指的内存地址,和strncpy不同, memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。
mem开头的函数则不关心'\0'字符,或者说这些函数并不把参数当字符串看待,因此参数的指针类型是void *而非char *。
memmove
void *memmove(void *dest, const void *src, size_t n);
memmove也是从src所指的内存地址拷贝n个字节到dest所指的内存地址,虽然叫move但其实也是拷贝而非移动。
但是和memcpy有一点不同, memcpy的两个参数src和dest所指的内存区间如果重叠则无法保证正确拷贝,而memmove却可以正确拷贝。
连接字符串
strcat
char * strcat( char * dst, char const *src );
函数的功能是把 src 字符串添加在 dst 原有字符串的后面,去掉原有的 '\0' 将字符串添加到后面并加上一个 '\0' 。
要确保目标字符数组有足够的空间,返还值也是操作后的字符串的指针。
strncat
char * strncat ( char *dst ,char const *src ,size_t len);
strncat函数通过参数n指定一个长度,可以避免缓冲区溢出错误。
注意这个参数n的含义和strncpy的参数n不同,它并不是缓冲区dest的长度,而是表示最多从src缓冲区中取n个字符(不包括结尾的'\0')连接到dest后面。如果src中前n个字符没有出现'\0',则取前n个字符再加一个'\0'连接到dest后面,所以strncat总是保证dest缓冲区以'\0'结尾,这一点又和strncpy不
同, strncpy并不保证dest缓冲区以'\0'结尾。所以,提供给strncat函数的dest缓冲区的大小至少应该是strlen(dest)+n+1个字节,才能保证不溢出。
字符串比较
strcmp
int strcmp (char const *s1, char const *s2 );
函数的功能是 将两个字符串的字符逐一比较,直到发现不匹配为止,那个优先不匹配的较“小”,这种比较叫做字典比较。如果 s1 小于 s2 返回一个小于零的值,如果 s1 大于 s2 ,返回一个大于零的值,如果两个参数相等返回零。
strncmp
int strncmp(char const *s1, char const *s2, size_t len);
strncmp的比较结束条件是:要么在其中一个字符串中遇到'\0'结束,要么比较完n个字符结束。
memcmp
int memcmp(const void *s1, const void *s2, size_t n);
memcmp从前到后逐个比较缓冲区s1和s2的前n个字节(不管里面有没有'\0'),如果s1和s2的前n个字节全都一样就返回0,如果遇到不一样的字节, s1的字节比s2小就返回负值, s1的字节比s2大就返回正值。