发布时间:2023-12-01 18:00
目录
求字符串长度
1.strlen
长度不受限制的字符串函数
2.strcpy
3.strcat
4.strcmp
长度受限制的字符串函数
5.strncpy,strncat,strncmp
字符串查找
6.strstr
字符串切割
7.strtok
错误信息报告
8.strerror
内存操作函数
9.memcpy
10.memmove
11.memcmp
12. memset
其他
13.一些其他字符串函数
size_t strlen ( const char * str );
具体功能:
求字符串的长度。
举例如下:
#include
#include void main() { char buffer[61] = "How long am I?"; int len; len = strlen( buffer ); printf( "'%s' is %d characters long\n", buffer, len ); }
注意事项:
1.字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。
2.参数指向的字符串必须要以 '\0' 结束。
3.注意函数的返回值为size_t,是无符号的( 易错 )
eg.
#include
int main() { const char*str1 = "abcdef"; const char*str2 = "abc"; if(strlen(str2)-strlen(str1)>0) { printf("str2>str1\n"); } else { printf("srt1>=str2\n"); } return 0; } 由于strlen返回的是无符号数,两个无符号数做运算,结果依然是无符号数,无符号数大于等于0,所以最终打印的结果为str2>str1。
那要如何修改才能比较呢?
if((int)strlen(str2)-(int)strlen(str1)>0)
将其强转为int类型就可以运算了,也可以直接比较二者大小
4.strlen中也可直接放置常量字符串
eg.
int main() { printf("%u", strlen("abc")); return 0; }
模拟实现:
int my_strlen(const char * str) { int count = 0; while(*str) { count++; str++; } return count; }
char* strcpy(char * destination, const char * source );
具体功能:
将Source所指空间中的字符串(从开始到第一次遇到\0的所有字符,包括\0)复制到Dest所指的空间中(会覆盖dest中的原字符串),然后返回char * Destination。
eg.
我们发现原本arr1中的xxxxxx被替换为hello\0
注意事项:
1.源字符串必须以 '\0' 结束。
eg.
2.会将源字符串中的 '\0' 拷贝到目标空间。
3.目标空间必须足够大,以确保能存放源字符串。
4.目标空间必须可变。
模拟实现:
char *my_strcpy(char *dest, const char*src) { char *ret = dest; assert(dest != NULL); assert(src != NULL); //先将*src赋给*dest,然后两者再++ //如果*src所指不为\0,赋值给*dest,然后while判断不为0,继续循环 //如果*src所指为\0,也会先赋给*dest,然后while判断为0,退出循环 while((*dest++ = *src++)) { ; } return ret; }
char * strcat ( char * destination, const char * source );
具体功能:
将Source所指的的内容追加到Dest所指的内容之后(从Dest所指字符串的第一个\0开始追加,一直追加到Source所指内容的第一个\0),最后返回Dest的起始地址。
eg.
注意事项:
1.源字符串必须以 '\0' 结束。
2.目标空间必须有足够的大,能容纳下源字符串的内容。
3.目标空间必须可修改。
模拟实现:
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; }
int strcmp ( const char * str1, const char * str2 );
具体功能:
第一个字符串大于第二个字符串,则返回大于0的数字 ;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字。
两个字符数组逐个字符比较,比较两个字符的ASCII码值,str1>str2返回大于零的数,str1=str2,返回0,str1
eg.
注意事项:
1.strcmp是比较字符串内容的,不是比较长度的。
模拟实现:
int my_strcmp(const char* s1, const char* s2) { assert(s1 && s2); while (*s1 == *s2) { if (*s1 == '\0') return 0; s1++; s2++; } return *s1 - *s2; }
char * strncat ( char * destination, const char * source, size_t num ); char * strncat ( char * destination, const char * source, size_t num ); int strncmp ( const char * str1, const char * str2, size_t num );
具体功能:
同strcpy,只是限制了拷贝的长度,保证了安全。
注意事项:
1.如果源字符串的长度小于count,则拷贝完源字符串之后,在目标的后边追加\0,直到count个。
eg.
具体功能:
同strcat,只是限制了追加的长度,保证了安全。
注意事项:
1.将Source中count个字符串追加到Dest后,会自动追加一个\0。
2.追加时无论count为多少,追加到Source中的\0自动停止。
具体功能:
比较到出现另个字符不一样或者一个字符串结束或者count个字符全部比较完。
char * strstr ( const char *str2, const char * str1);
具体功能:
在string所指的字符串中寻找CharSet所指的字符串,并返回CharSet在string第一次出现的地址;如未找到,则返回NULL。
eg.
注意事项:
1.如果在string中有多个CharSet的字符串,只会返回第一个出现的地址
模拟实现:
char* my_strstr(const char*str1, const char* str2) { assert(str1 && str2); // char* s1; char* s2; char* cp = str1; if (*str2 == '\0')//系统规定,可忽略 return str1; while (*cp) { s1 = cp; s2 = str2; //while (*s1!='\0' && *s2 != '\0' && *s1 == *s2) while (*s1 && *s2 && *s1 == *s2) { s1++; s2++; } if (*s2 == '\0')//当找到\0时,停止 { return cp; } cp++; } //找不到 return NULL;
char * strtok ( char * str, const char * sep );
具体功能:
1.Del参数是个字符串,定义了用作分隔符的字符集合第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
2.strtok函数找到Token中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(vs下测试结果是返回一个指向标记前面字符串的指针)(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
3.strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
4.strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
5.如果字符串中不存在更多的标记,则返回 NULL 指针。
eg.
char * strerror ( int errnum );
具体功能:
返回错误码所对应的错误信息。
C语言库函数调用失败的的时候,会把错误码储存到errno变量中。
eg.
也可用perror打印错误信息
void * memcpy ( void * destination, const void * source, size_t num );
具体功能:
函数memcpy从src的位置开始向后复制count个字节的数据到destination的内存位置。(不限制数据内存)
eg.
注意事项 :
1.这个函数在遇到 '\0' 的时候并不会停下来。
2.如果source和destination有任何的重叠,复制的结果都是未定义的。
模拟实现:
void* my_memcpy(void* dest, const void*src, size_t count) { void* ret = dest; assert(dest && src); while (count--) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } return ret; }
void * memmove ( void * destination, const void * source, size_t num );
具体功能:
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
eg.
模拟实现:
void* my_memmove(void* dest, const void* src, size_t count) { void* ret = dest; assert(src && dest); if (dest < src) { //前->后 while (count--) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } } else { //后->前 while (count--) { *((char*)dest+count) = *((char*)src + count); } } return ret; }
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
具体功能:
比较从buf1和buf2指针开始的count个字节。
eg.
试着仿照前文的模拟实现,实现memcmp吧
具体功能:
将dest中的count个字节设置为c
eg.
字符分类函数:
字符转换函数:
int tolower ( int c );//把给定的字母转换为小写字母
int toupper ( int c );//把给定的字母转换为大写字母
gets:字符串输入
puts:字符串输出
atof,atoi:字符串转换为数值
sprint,sscanf:字符串格式化输入,输出
以上就是本次的分享内容了,喜欢我的分享的话,别忘了点赞加关注哟!
如果你对我的文章有任何看法,欢迎在下方评论留言或者私信我鸭!
我是白晨,我们下次分享见!!