1.strlen()
size_t strlen ( const char * str );
注:
- 字符串是以’\0’结尾,strlen计算的长度不包括’\0’。
- 参数指向的字符串必须以’\0’结束。
- size_t为无符号数标志。
1.1 strlen模拟实现
size_t my_strlen(const char* str) { const char* p = str; while (*(str++)); return str-p-1; }
2.strcpy()
字符串拷贝函数
char* strcpy(char * destination, const char * source );
注:
- 源字符串必须以’\0’结束。
- 会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 目标空间必须足够大,确保能存放源字符串。
- 目标空间必须可变。
2.1strcpy模拟实现
char* my_strcpy(char* destination, const char* source) { assert(destination != NULL); assert(source != NULL); while (*destination++ = *source++); return destination; }
2.2 strncpy
拷贝num个字符从suurce->destination。
char * strncpy ( char * destination, const char * source, size_t num );
注:
- 拷贝num个字符从源字符串到目标空间。
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
3.strcat
字符串追加函数
char * strcat ( char * destination, const char * source );
注:
- 源字符串必须以’\0’结束。
- 目标空间必须足够大,能容下源字符串内容。
- 目标空间必须可修改。
- 不可以自己给自己追加!
3.1 strcat模拟实现
char* my_strcat(char * destation,const char *source) { assert(destation != NULL); assert(source != NULL); int len = strlen(destation); char* str = destation + len; while (*str++ = *source++); return destation; }
3.2 strncat
在destination末尾追加num个字符内容。
char * strncat ( char * destination, const char * source, size_t num );
示例:
int main () { char str1[20]; char str2[20]; strcpy (str1,"To be "); strcpy (str2,"or not to be"); strncat (str1, str2, 6); puts (str1); return 0; }
4.strcmp
字符串比较函数
int strcmp ( const char * str1, const char * str2 );
标准规定:str1>str2,return >0
str1==str2,return 0
str1<str2 ,return <0;
4.1strcmp模拟实现
int my_strcmp(const char *str1,const char * str2) { assert(str1 != NULL); assert(str2 != NULL); int sz_str1 = strlen(str1); int sz_str2 = strlen(str2); int max = sz_str1 > sz_str2 ? sz_str1 : sz_str2; for (int i = 0; i < max; i++) { if (*str1 == *str2) { str1++; str2++; } else if (*str1 > *str2) { return 1; } else { return -1; } } return 0; }
4.2strncmp
比较到出现一个字符不一样或者一个字符串结束或者num个字符全部比较完。
int strncmp ( const char * str1, const char * str2, size_t num );
示例:
5.strstr()
字符串模式匹配(返回str2在str1中的第一个位置指针)
char * strstr ( const char *str1, const char * str2);
5.1 strstr模拟实现
char* my_strstr(const char* str1, const char* str2) { assert(str1 != NULL); assert(str2 != NULL); char* p1 = str1; char* p2 = str2; while (*p1 != '\0') { if (*p1 != *p2) { p1++; } else { while (*p1 == *p2) { p1++; p2++; if (*p2 == '\0') { return p1 - (p2 - str2); } } //p1退回刚比较时的下一个,p2到达初始值 p1 = p1-(p2 - str2-1); p2 = str2; } } return NULL; }
优化版本:
char * strstr (const char * str1, const char * str2) { char *cp = (char *) str1; char *s1, *s2; if ( !*str2 ) return((char *)str1); while (*cp) { s1 = cp; s2 = (char *) str2; while ( *s1 && *s2 && !(*s1-*s2) ) s1++, s2++; if (!*s2) return(cp); cp++; } return(NULL);
6.memcpy
内存操作函数:从source复制num个字符到destination(不可重叠)。
void * memcpy ( void * destination, const void * source, size_t num );
注:
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 ‘\0’ 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
6.1 memcpy模拟实现
char* my_memcpy(char* destination, char* source, int num) { char* tem = destination; assert(destination); assert(source); while (num--) { *tem++ = *source++; } return destination; }
7.memmove
内存移动函数:就是将source的num个字节内容搬到destination去(可重叠)。
void * memmove ( void * destination, const void * source, size_t num );
注:
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
7.1memmove模拟实现
char* my_memmove(char* destination, char* source, int num) { //从后往前复制 assert(destination); assert(source); char* des_cur = destination + num - 1; char* sou_cur = source + num - 1; while (sou_cur != source) { *des_cur-- = *sou_cur--; } return destination; }
8.memcmp
内存比较函数:比较num个字节数
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
8.1memcmp模拟实现
int my_memcmp(const char* str1, const char* str2, int num) { assert(str1); assert(str2); while (num--) { if (*str1 == *str2) { str1++; str2++; } else if (*str1 > *str2) { return 1; } else { return -1; } } return 0; }
9.strtok
字符串查找标记:用sep中的标记查找str,返回标记的位置。
char * strtok ( char * str, const char * sep );
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
- strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
示例:
10.strerror/perror
错误信息报告函数:返回错误码所对应的信息的指针。
char * strerror ( int errnum );
errno:全局变量。错误信息会自动存里面去。
每种错误码都对应一个错误信息:
出错会将错误码自动存到errno中,这样直接打印即可。
直接打印出错误信息。参数是修饰的:
void perror( const char *string );(stdlib.h)
11.memset
用c初始化dest的空间,字节数为count;
void *memset( void *dest, int c, size_t count );
12.字符分类函数
函数 | 如果他的参数符合下列条件就返回真 |
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母a~z或A~Z |
isalnum | 字母或者数字,a~z,A~Z,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
以上是字符串函数详细介绍,如有问题,恳请大佬指点💖