C语言字符串函数与内存函数精讲
目录
- strlen
- strcpy
- strcat
- strcmp
- strncpy
- strncat
- strncmp
- strstr
- strtok
- strerror
- tolower\toupper
- memcpy
- memmove
- memcmp
- memset
strlen
获取字符串长度。
strlen - size_t strlen( const char *string );
1.字符串以’\0’作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数(不包含’\0’).
2.参数指向的字符串必须要以’\0’结束。
3.注意函数的返回值为size_t,是无符号的(易错)
strlen模拟实现
//size_t strlen(const char *string); #include<stdio.h> #include<assert.h> size_t my_strlen(const char* str) { assert(str != NULL); int count = 0; while (*str) { count++; str++; } return count; } int main() { int len = my_strlen("abcedfg"); printf("%d\n", len); return 0; }
strcpy
复制一个字符串
strcpy - char *strcpy( char *strDestination, const char *strSource );
1.源字符串必须以’\0’结束。
2.会将源字符串中的’\0’拷贝到目标空间。
3.目标空间必须足够大,以确保存放源字符串。
4.目标空间必须可变。
strcpy的模拟实现
#include<stdio.h> #include<assert.h> char* my_strcpy(char* dest, const char* src) { assert(dest && src); char* ret = dest; //将src指向的字符串拷贝到dest指向的空间中,包括'\0' while (*dest++ = *src++) ; //返回目的地空间的起始地址 return ret; } int main() { //char* arr1 = "abcdefghi";//err 目标空间必须可变 char arr1[] = "abcdefghi"; //char arr2[] = { 'h','e','l','l','o' };//err 源字符串必须以'\0'结尾 char arr2[] = "hello"; my_strcpy(arr1, arr2); printf(arr1); return 0; }
strcat
字符串追加
strcat - char *strcat( char *strDestination, const char *strSource );
1.源字符串必须以’\0’结束。
2.目标空间必须足够大,能容纳下源字符串的内容。
3.目标空间必须可修改。
4.不能自己给自己追加。
strcat的模拟实现
#include<stdio.h> #include<assert.h> char* my_strcat(char* dest, char* src) { char* ret = dest; assert(dest && src); //1.找到目的字符串中的'\0' while (*dest) dest++; //2.追加 while (*dest++ = *src++) ; return ret; } int main() { char arr1[37] = "hello"; char arr2[] = "world"; my_strcat(arr1, arr2);//在arr1后面追加arr2 printf("%s\n", arr1); return 0; }
strcmp
字符串比较
strcmp模拟实现
#include<stdio.h> #include<assert.h> int my_strcmp(const char* str1, const char* str2) { assert(str1 && str2); while (*str1 == *str2) { if (*str1 == '\0') { return 0;//相等 } str1++; str2++; } return *str1 - *str2; } int main() { char* p1 = "abcdef"; char* p2 = "abqjf"; int ret = my_strcmp(p1, p2); printf("%d\n", ret); return 0; }
strncpy
将一个字符串中的字符复制到另一个字符串中。
strncpy - char *strncpy( char *strDest, const char *strSource, size_t count );
1.拷贝count个字符从源字符串到目标空间。
2.如果源字符串的长度小于count,则拷贝完源字符串之后,在目标的后边追加0,直到count个。
strncpy模拟实现
char* my_strncpy(char* dest, const char* src, size_t count) { char* ret = dest; while (count && (*dest++ = *src++)) { count--; } if (count) { while (--count) { *dest++ = '\0'; } } return ret; } int main() { char arr1[20] = { 0 }; char arr2[] = "hey"; my_strncpy(arr1, arr2, 6); printf(arr1); return 0; }
strncat
字符串的附加字符。
strncat - char *strncat( char *Dest, const char *Source, size_t count );
strncat模拟实现
char* my_strncat(char* dest, const char* src, size_t count) { char* ret = dest; while (*dest++) ; dest--; while (count--) { if (!(*dest++ = *src++)) { return ret; } } *dest = '\0'; return ret; } int main() { char arr1[37] = "hello"; char arr2[] = "world"; my_strncat(arr1, arr2, 7); puts(arr1); return 0; }
strncmp
比较两个字符串的字符。
strncmp - int strncmp( const char *string1, const char *string2, size_t count );
1.比较到出现一个字符不一样或者一个字符串结束或者count个字符串全部比较完。
strstr
查找子字符串
strstr - char *strstr( const char *string, const char *strCharSet );
1.每个函数都返回一个指向strCharSet在string中首次出现的指针,如果strCharSet没有在string中出现,则返回NULL。如果strCharSet指向长度为0的字符串,则函数返回string。
strstr模拟实现
#include<stdio.h> #include<assert.h> char* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); char* cur = (char*)str1; char* s1, * s2; if (!*str2) return ((char*)str1); while (*cur) { s1 = cur; s2 = (char*)str2; while (*s1 && *s2 && !(*s1 - *s2)) { s1++; s2++; } if (!*s2) return cur; cur++; } return NULL; } int main() { char* p1 = "aqqqcdef"; char* p2 = "qqc"; char* ret = my_strstr(p1, p2); if (ret == NULL) printf("字串不存在\n"); else printf("%s\n", ret); return 0; }
strtok
切割字符串,查找字符串中的下一个令牌
strtok - char * strtok ( char * str, const char * sep );
1.sep参数是个字符串,定义了用作分隔符的字符集合。
2.第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
3.strtok函数找到str中的下一个标记,并将其用’\0’结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用
strtok函数切分的字符串一般都是临时拷贝的内容并且可修改)。
4.strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
5.strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
6.如果字符串中不存在更多的标记,则返回NULL指针。
int main() { char arr[] = "hyr@baidu.com"; char* p = "@."; char buf[1024] = { 0 }; strcpy(buf, arr); char* ret = NULL; for (ret = strtok(arr, p);ret != NULL;ret = strtok(NULL, p)) { printf("%s\n", ret); } return 0; }
strerror
获取系统错误消息(strerror)或打印用户提供的错误信息。
strerror - char *strerror( int errnum );
1.返回错误码所对应的错误信息。
2.errno是一个全局的错误码的变量,当C语言的库函数在执行过程中发生了错误,就会把对应的错误码赋值到errno中。
#include<stdio.h> #include<string.h> #include<errno.h>//必须包含的头文件 int main() { FILE* pf = fopen("unexist.ent", "r"); if (pf == NULL) { printf("Error opening file unexist.ent:%s\n", strerror(errno)); //errno: Last error number return 0; } //.... return 0; }
tolower\toupper
int tolower ( int c) ;
- 大写字母转化为小写字母
int toupper ( int c) ;
- 小写字母转化为大写字母
memcpy
在缓冲区之间复制字符
memcpy - void * memcpy ( void * dest, const void * source, size_t num );
1.函数memcpy从source的位置开始向后复制num个字节的数据到destation的内存位置。
2.这个函数在遇到\0的时候并不会停下来。
3.如果source和destion有任何的重叠,复制的结果都是未定义的。
memcpy模拟实现
#include<stdio.h> #include<assert.h> struct Stu { char name[20]; int age; }; void* my_memcpy(void* dest, const void* src, size_t num) { assert(dest && src); void* ret = dest; while (num--) { *((char*)dest) = *((char*)src); ++(char*)dest; ++(char*)src; } return ret; } int main() { struct Stu arr1[] = { {"zhangsan",13},{"lisi",17} }; struct Stu arr2[3] = { 0 }; my_memcpy(arr2, arr1, sizeof(arr1)); return 0; }
memmove
将一个缓冲区移动到另外一个缓冲区
memmove - void *memmove( void *dest, const void *src, size_t count );
1.和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
2.如果源空间和目标空间出现重叠,就得使用memmove函数处理。
memmove模拟实现
#include<stdio.h> #include<assert.h> void* my_memmove(void* dest, const void* src, size_t count) { assert(dest && src); void* ret = dest; if (dest < src) { while (count--) { *(char*)dest = *(char*)src; ++(char*)dest; ++(char*)src; } } else { while (count--) { *((char*)dest + count) = *((char*)src + count); } } return ret; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; //将1,2,3,4,5数据拷贝到3,4,5,6,7空间上去 my_memmove(arr + 2, arr, 20); for (int i = 0;i < 10;i++) { printf("%d ", arr[i]); } return 0; }
memcmp
比较两个缓冲区间的字符
memcmp - int memcmp( const void *buf1, const void *buf2, size_t count );
1.比较从buf1和buf2指针开始的count个字节
memset
将缓冲区设定为指定的字符
menset - void *memset( void *dest, int c, size_t count );
到此这篇关于C语言字符串函数与内存函数精讲的文章就介绍到这了,更多相关C语言字符串与内存函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!