#include<string.h> 是C语言中的一个常用的头文件,其定义了许多关于字符串操作的函数和一些其它函数,如:strlen、strcpy、strcap、memcpy、memmove等。
文章目录
- 1、求字符串长度:strlen
- strlen的使用
- strlen模拟实现
- 2、拷贝函数:strcpy、strncpy
- strcpy的使用
- strcpy的模拟实现
- strncpy的使用
- 3、追加函数:strcat、strncat
- strcat的使用
- strcat的模拟实现
- strncat的使用
- 4、比较两个字符串的大小:strcmp 、strncmp
- strcmp的使用
- strcmp的模拟实现
- strncmp的使用
- 5、字符串查找函数:strstr
- strstr的使用
- strstr的模拟实现
- 6、分割字符串函数:strtok
- strtok的使用
- 7、错误信息报告函数:strerror
- 举例使用
- 8、内存操作函数:memcpy、memmove、memset、memcmp
- (1)memcpy内存拷贝函数
- memcpy的使用:
- memcpy的模拟实现
- (2)memmove内存拷贝函数
- memmove的使用
- memmove的模拟实现
- (3)memset内存设置函数
- memset的使用
- (4)memcmp内存比较函数
- memcmp的使用
- 9、字符分类函数
- 举例使用
- 10、转换大小写
- 举例使用
1、求字符串长度:strlen
size_t strlen( const char* string );
作用:求字符串的长度。
注意:
1.注意函数的返回值为size_t,是无符号的。
2. strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
3. 参数指向的字符串必须要以 ‘\0’ 结束。
strlen的使用
strlen模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strlen(const char* str)
{
int count = 0;
assert(str != NULL);//进行断言,不为空,为空会报警告
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char ch[] = "abcdef";
int n = my_strlen(ch);
printf("%d\n", n);
return 0;
}
2、拷贝函数:strcpy、strncpy
char *strcpy( char*strDestination, const char*strSource);
**作用:**将一个字符串的内容拷贝到另一个字符串内
注意:
- 源字符串必须以 ‘\0’ 结束。
- 会将源字符串中的 ‘\0’ 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。 如:将ch2拷贝到ch1中,若char*ch1=“abcdefghi”; 则会崩溃,因为ch1是指向的是常量字符串,若将ch2拷贝到ch1会崩溃。
- 只能拷贝字符串,若要拷贝 int ch1[ ]={1,2,3,4,5} 放在 int ch2[100]={ 0 } 中,则不行 若要拷贝,则应使用 memcpy函数。
strcpy的使用
strcpy的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* str1, const char* str2)
{
assert(str1 != NULL);
assert(str2 != NULL);
char* ret = *str1;
while (*str2 != '\0')
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return ret;
}
int main()
{
char ch1[10] = "abcdefgh";
char ch2[] = "xxxxxx";
my_strcpy(ch1, ch2);1
printf("%s\n", ch1);
return 0;
}
strncpy的使用
char*strncpy( char*strDest, const char*strSource, size_t count );
size_t count 意思是比较前count个字符
3、追加函数:strcat、strncat
char* strcat( char*strDestination, const char*strSource );
作用:将一个字符串的内容追加到另一个字符串的后面
注意:
- 源字符串必须以 ‘\0’ 结束。 如:ch2={‘b’,‘i’,‘t’}则会崩溃
- 目标空间必须有足够的大,能容纳下源字符串的内容。如:char ch1[ ]=“abcdef” 将ch2追加到ch1会崩溃 ,应为char ch1[100]=“abcdef”
- 目标空间必须可修改。
strcat的使用
strcat的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(char* str1, const char* str2)
{
assert(str1 != NULL);
assert(str2 != NULL);
char* ret = str1;
while (*str1 != '\0')
{
str1++;
}
while (*str2 != '\0')
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return ret;
}
int main()
{
char ch1[100] = "abcdefgh";
char ch2[] = "xxxxxx";
my_strcat(ch1, ch2);//将ch2的内容追加到ch1后面
printf("%s\n", ch1);
return 0;
}
strncat的使用
int strncmp( const char*string1, const char*string2, size_t count );
size_t count 意思是比较前count个字符
4、比较两个字符串的大小:strcmp 、strncmp
int strcmp( const char*string1, const char*string2 );
作用:比较两个字符串的大小。
使用方法:通过函数的返回值来比较大小。
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
字符串的比较原理:
比较ASCII码值(如比较ch1[ ]=“aqwer”;与ch2[ ]=“abwer”😉
若ch1[]为”aqwer”则先a与a比较,相等,再比较b与q,b<q,所以p2>p1
若ch2[ ]为”abwer”,原理同上。
strcmp的使用
strcmp的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 != NULL);
assert(str2 != NULL);
while (*str1 == *str2)
{
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
else
return -1;
}
int main()
{
char ch1[] = "aqwer";
char ch2[] = "abwer";
int n = my_strcmp(ch1, ch2);
if (n > 0)
printf("ch1大于ch2\n");
else if (n == 0)
printf("ch1等于ch2\n");
else
printf("ch1小于ch2\n");
return 0;
}
strncmp的使用
int strncmp( const char*string1, const char*string2, size_t count );
size_t count 意思是比较前count个字符。
5、字符串查找函数:strstr
char*strstr( const char*string, const char*strCharSet );
作用:找子串( 在字符串1中找是否包含字符串2,找到了返回字符串1中与字符串2首元素相同的元素的地址,若未找到则返回值为空 )
strstr的使用
strstr的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 != NULL);//确保str1不为空指针
assert(str2 != NULL);//确保str2不为空指针
while (*str1 != '\0')
{
char* ret = str1;
char* p1 = str1;
char* p2 = str2;
while ((*p1 == *p2)&&(*p1!='\0')&&(*p2!='\0'))
{
p1++;
p2++;
}
if (*p2 == '\0')
{
return ret;
}
if (*p1 == '\0')
{
return NULL;
}
str1++;
}
return NULL;
}
int main()
{
char ch1[] = "abcdefghijklmn";
char ch2[] = "lmn";
char* ret = my_strstr(ch1, ch2);
if (ret != NULL)
printf("找到了\n");
else
printf("未找到\n");
return 0;
}
6、分割字符串函数:strtok
char*strtok( char*strToken, const char*strDelimit );
作用:将字符串进行分割,如ch1[ ]=“312456781425@qq.com”; 与 ch2[ ]=“@.”; 可以将其分割为312456781425 与 qq 与 com
strtok原理(strtok具有记忆功能):
1、strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
2、strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。 如果字符串中不存在更多的标记,则返回NULL 指针。
举例:在ch1中”312456781425@qq.com”找ch2中所包含的元素:
- char* ret = strtok(ch1, ch2); 当找到 @ 时,将 @ 替换成’\0’,打印printf(“%s\n”, ret)时到’\0’停止,相当于只打印312456781425
- 此时strtok会保存被替换成’\0’的 @ 的地址,下一个打印时只要将ch1替换成NULL,再找一个接收
- 此时写为ret = strtok(NULL, ch2),再打印printf(“%s\n”, ret),会打印qq
- 接下来同理打印出com
strtok的使用
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{
char ch1[] = "312456781425@qq.com";
char ch2[] = "@.";
char* ret = NULL;
for (ret = strtok(ch1, ch2); ret != NULL; ret = strtok(NULL, ch2))
{
printf("%s\n", ret);
}
return 0;
}
7、错误信息报告函数:strerror
char*strerror( int errnum );
以下是VS2022中的错误码与错误信息
错误码 | 错误信息 |
0 | No error |
1 | Operation not permitted |
2 | No such file or directory |
3 | No such process |
. . . . . . |
错误码变量errno:errno 是一个全局的错误码变量,当c语言的库函数在执行过程中发生了错误,就会把对应的错误码赋值到errno中。
作用:通过错误码报告错误信息。
打印错误码中的错误信息:
举例使用
打开文件失败返回错误码
8、内存操作函数:memcpy、memmove、memset、memcmp
以上函数都是与字符串相关,但如果涉及到int、double、float则无法使用,而内存拷贝函数可以进行相关操作。
(1)memcpy内存拷贝函数
作用:进行内存拷贝,与strcpy类似
void*memcpy( void*dest, const void*src, size_t count );
注:size_t是无符号整形unsigned(size_t count是指以字节为单位拷贝)
memcpy的使用:
memcpy的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* str1, const void* str2, size_t count)
{
assert(str1 != NULL);
assert(str2 != NULL);
char* ret = str1;
while (count--)
{
*(char*)str1 = *(char*)str2;
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[] = { 1,1,1,1,1,1 };
my_memcpy(arr1, arr2, 24);
//将arr2中的内容拷贝到arr1中,24的意思是24个字节,即4*6=24
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
printf("\n");
return 0;
}
注:memcpy不能自己拷贝自己,如:memcpy( arr1+2, arr2, 20 ),会出现内存重叠。若要自己拷贝自己,应使用memmove函数。
(2)memmove内存拷贝函数
void*memmove( void*dest, const void*src, size_t count );
(size_t count是指以字节为单位拷贝)
memmove函数与memcpy类似,都是进行内存拷贝,但功能比memcpy更强大(可以自己拷贝自己)
memmove的使用
memmove的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* str1, void* str2, size_t count)
{
assert(str1 != NULL);
assert(str2 != NULL);
void* ret = str1;
if (str1 < str2)
{
while (count--)
{
*(char*)str1 = *(char*)str2;
++(char*)str1;
++(char*)str2;
}
}
else
{
while (count--)
{
*((char*)str1 + count) = *((char*)str2 + count);
}
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[] = { 1,1,1,1,1,1 };
my_memmove(arr1+2, arr1, 24);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
printf("\n");
return 0;
}
(3)memset内存设置函数
void*memset( void*dest, int c, size_t count );
作用:进行内存设置(size_t count是指以字节为单位设置)。
memset的使用
(4)memcmp内存比较函数
int memcmp( const void*buf1, const void*buf2,s ize_t count );
作用:进行内存比较,与strcmp类似
使用方法:通过函数的返回值来比较大小。
第一个字节内容大于第二个字节内容,返回大于0的数字
第一个字节内容等于第二个字节内容,则返回0
第一个字节内容小于第二个字节内容,则返回小于0的数字
memcmp的使用
9、字符分类函数
函数 | 如果他的参数符合下列条件就返回真 |
iscntrl | 任何控制字符 |
isspace | 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’ |
isdigit | 十进制数字 0~9 |
isxdigit | 十六进制数字,包括所有十进制数字,小写字母af,大写字母AF |
islower | 小写字母a~z |
isupper | 大写字母A~Z |
isalpha | 字母az或AZ |
isalnum | 字母或者数字,az,AZ,0~9 |
ispunct | 标点符号,任何不属于数字或者字母的图形字符(可打印) |
isgraph | 任何图形字符 |
isprint | 任何可打印字符,包括图形字符和空白字符 |
举例使用
其它自行尝试。
10、转换大小写
int tolower ( int c ); 将大写转换为小写
int toupper ( int c ); 将小写转换为大写
举例使用
文章出处登录后可见!