文章目录
前言一、字符串函数1.求字符串长度 strlen2.长度不受限制的字符串函数strcpy、strcat、strcmp字符串拷贝 strcpy字符串追加拷贝 strcat字符串比较 strcmp3.长度受限制的字符串函数strncpy、strncat、strncmp字符串拷贝 strncpy字符串追加拷贝 strncat字符串比较 strncmp4.判断字符串匹配问题 strstr5.字符操作字符分类函数字符转换函数二、内存操作函数1.memcpy2.memmove三、库函数模拟实现1.strlen2.strcpy3.strcat4.strcmp5.memcpy6.memmove前言
最近在刷题的时候,经常遇到需要用到字符串函数的问题,因此发现对这方面函数使用的一些不足,遂写一篇博客(笔记),巩固自身也便复习。
一、字符串函数
1.求字符串长度 strlen
函数定义:
size_t strlen ( const char * str );
注意点:
字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。参数指向的字符串必须要以 ‘\0’ 结束。注意函数的返回值为size_t,是无符号的( 易错 )
2.长度不受限制的字符串函数strcpy、strcat、strcmp
字符串拷贝 strcpy
函数定义:
char* strcpy(char * destination, const char * source );
注意点:
源字符串必须以 ‘\0’ 结束。会将源字符串中的 ‘\0’ 拷贝到目标空间。目标空间必须足够大,以确保能存放源字符串。目标空间必须可变。
Strcpy的作用是将一个数组的字符串以覆盖的方式复制到另一个数组,由于‘\0’也被复制,所以相当于完全拷贝。strcpy会返回一个char型指针,该指针指向被覆盖的目标字符串的第一个字符的地址。
例如:
#include<stdio.h>#include<string.h>//strcpy的作用以及用法int main(){char a[32]="America";char b[32]="China";strcpy(a,b); // 将b的内容覆盖复制到aprintf("%s\n%s",a,b);return 0;}
以上代码的结果为:
ChinaChina
字符串追加拷贝 strcat
函数定义:
char * strcat ( char * destination, const char * source );
注意点:
源字符串必须以 ‘\0’ 结束。目标空间必须有足够的大,能容纳下源字符串的内容。目标空间必须可修改。
Strcat的用法与strcpy相似,作用是以拼接的方式,将源字符串的内容追加拷贝到目标字符串后面。
例如:
#include<stdio.h>#include<string.h>int main(viod){char c[32]="America";char d[32]="China";strcat(c,d);printf("%s\n",c);return 0;}
以上代码的结果为:
AmericaChina
字符串比较 strcmp
函数定义:
int strcmp ( const char * str1, const char * str2 );
注意点:
第一个字符串大于第二个字符串,则返回大于0的数字第一个字符串等于第二个字符串,则返回0第一个字符串小于第二个字符串,则返回小于0的数字
strcmp函数按照ASCII码来比较两字符串每一位字符的的大小,直到出现不同的字符or遇到‘\0’为止。当某一个字符串提前结束(遇到‘\0’),那么就算做另一个字符串比较‘大’。
3.长度受限制的字符串函数strncpy、strncat、strncmp
strncpy、strncat、strncmp三个函数的作用与strcpy、strcat、strcmp几乎完全一样,唯一不同的是他们多了一个参数,所以这里只给出其函数定义及注意点:
字符串拷贝 strncpy
函数定义
char * strncpy ( char * destination, const char * source, size_t num );
注意点:
拷贝num个字符从源字符串到目标空间。如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
字符串追加拷贝 strncat
函数定义
char * strncat ( char * destination, const char * source, size_t num );
注意点:
同strncpy
字符串比较 strncmp
函数定义
int strncmp ( const char * str1, const char * str2, size_t num);
注意点:
比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完
4.判断字符串匹配问题 strstr
函数定义
char * strstr ( const char *, const char * );
strstr(str1,str2)函数用于判断字符串str2是否是str1的子串。如果是、则返回str1字符串从str2第一次出现的位置到str1结尾的字符串,否则返回NULL。可以用来1.分割字符串;2.通过查找子串进行删除,修改等一系列操作。
5.字符操作
字符分类函数
字符转换函数
int tolower ( int c );//转换成小写 int toupper ( int c );//转换成大写
二、内存操作函数
1.memcpy
函数定义
void * memcpy ( void * destination, const void * source, size_t num );
注意点:
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。这个函数在遇到 ‘\0’ 的时候并不会停下来。如果source和destination有任何的重叠,复制的结果都是未定义的(存在内存重叠)。
memcpy与strcpy的区别
复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
2.memmove
函数定义
void * memmove ( void * destination, const void * source, size_t num );
注意点:
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。
三、库函数模拟实现
1.strlen
int my_strlen(char *s) {char *p = s; while(*p != ‘\0’ ) p++; return p-s; }
2.strcpy
char *my_strcpy(char *dest, const char*src) {char *ret = dest; assert(dest != NULL);assert(src != NULL); while((*dest++ = *src++)) {; } return ret; }}
3.strcat
char *my_strcat(char *dest, const char*src) {char *ret = dest; assert(dest != NULL); assert(src != NULL); while(*dest) {dest++; } //追加拷贝while((*dest++ = *src++)) {; } return ret; }
4.strcmp
int my_strcmp (const char * src, const char * dst) {int ret = 0 ; assert(src != NULL); assert(dest != NULL); while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) ++src, ++dst; if ( ret < 0 ) ret = -1 ; else if ( ret > 0 ) ret = 1 ; return( ret ); }
5.memcpy
void * memcpy ( void * dst, const void * src, size_t count) {void * ret = dst; assert(dst); assert(src); //从低地址向高地址拷贝while (count--) {*(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } return(ret); }
6.memmove
void * memmove ( void * dst, const void * src, size_t count) {void * ret = dst; //如果条件成立,表明向前拷贝不会出现内存重叠现象,采用memcpy相同方法拷贝,反之采用高地址向低地址拷贝if (dst <= src || (char *)dst >= ((char *)src + count)) {while (count--) {*(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } } else {dst = (char *)dst + count - 1; src = (char *)src + count - 1; while (count--) {*(char *)dst = *(char *)src; dst = (char *)dst - 1; src = (char *)src - 1; } } return(ret); }