目录
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
//strlen
//size_t strlen(const char* str)
//strlen用来求字符串的长度,指的是字符串中‘\0’前面的字符个数,不包括‘\0’;strlen的返回值为zize_t,即无符号整型
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abc\0def";
char arr3[3] = { 'a','b','c' };
int len1 = strlen(arr1);
int len2 = strlen(arr2);
int len3 = strlen(arr3);
printf("%d\n", len1); //6
printf("%d\n", len2); //3
printf("%d\n", len3); //15
printf("%u\n", strlen(arr2) - strlen(arr1)); //4294967293
//strlen的返回值为zize_t,即无符号整型;strlen(arr2)等于3,strlen(arr1)等于6,3-6=-3,在内存中存储的二进制序列是11111111111111111111111111111101
return 0;
}
//strlen的模拟实现
//1.计数器方式模拟
int count_str1(char* arr)
{
int count = 0;
while (*arr != '\0')
{
count++;
arr++;
}
return count;
}
//2.递归模拟
int count_str2(char* arr)
{
if (*arr == '\0')
return 0;
else
return 1 + count_str2(arr + 1);
}
//3.指针-指针模拟
int count_str3(char* arr)
{
char* s = arr;
while (*arr != '\0')
{
arr++;
}
return arr - s;//指针-指针的计算结果是两个指针之间相差的元素个数,需要区分正负号
}
int main()
{
char arr[] = "abcdef";
int len1 = count_str1(arr);
int len2 = count_str2(arr);
int len3 = count_str3(arr);
printf("%d\n", len1);
printf("%d\n", len2);
printf("%d\n", len3);
return 0;
}
//strcpy
//char* strcpy(char* destination, const char* source) 长度不受限制、不安全
//char* destination--->目标空间; const char* source--->源字符串;char* strcpy--->返回值是目标空间的起始地址,类型为 char*
//strcpy是将源字符串包括源字符串中的'\0'一起拷贝到目标空间(源字符串必须以'\0'结束);目标空间必须足够大,以确保能够存放源字符串;目标空间必须可变
int main()
{
char arr1[] = "abcd";
char arr2[20] = "defgeh";
strcpy(arr2, arr1);
//arr2是目标空间,arr1是源字符串;把源字符串拷贝到目标空间,包括源字符串中的'\0'也会被拷贝到目标空间中,函数的返回值是目标空间字符串的起始地址
printf("%s\n", arr2);
return 0;
}
//strcpy的模拟实现
char* copy_str(char* arr2, const char* arr1)
{
char* s = arr2;
while (*arr2 = *arr1)
{
arr2++;
arr1++;
}
//循环体也可以写成下面这样:
//while (*arr2++ = *arr1++)
//{
// ;
//}
return s;
}
int main()
{
char arr1[] = "abcd";
char arr2[20] = "defgeh";
copy_str(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
//strcat
//char* strcat(char* destination, const char* source) 长度不受限制、不安全
//char* destination--->目标空间; const char* source--->源字符串;char* strstr--->返回值是目标空间的起始地址,类型为 char*
//strcat是将源字符串的内容(包括'\0')追加到目标空间,对目标空间追加字符串是从目标字符串的第一个'\0'开始(覆盖'\0'),所以目标字符串和源字符串都必须包含'\0'
//strcat不可以实现字符串自己追加自己,会陷入死循环
int main()
{
char arr1[20] = "Thank \0dfghj";
char arr2[] = "You";
strcat(arr1, arr2);
//strcat从目标字符串的第一个'\0'开始追加(覆盖掉'\0'),追加结束后的目标字符串最后面是从源字符串追加过来的'\0';
printf("%s\n", arr1);
return 0;
}
//strcat的模拟实现
char* Concatenate_str(char* arr1, const char* arr2)
{
char* s = arr1;
while (*arr1)
{
arr1++;
}
while (*arr1++ = *arr2++)
{
;
}
return s;
}
int main()
{
char arr1[20] = "Thank \0dfghj";
char arr2[] = "You";
Concatenate_str(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
//strcmp
//int strcmp(const char* str1, const char* str2) 长度不受限制、不安全
//strcmp比较的是对应字符位置上的ASCII码值的大小,与字符串长度无关;从左往右遇到的第一个对应字符不相同时,这一对字符中,谁的ASCII码值大,对应的字符串就大,
//str1大于str2,返回一个大于0的数,相等返回0,小于返回一个负数
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abcdddd";
int ret = strcmp(arr1, arr2);
//strcmp比较的是对应字符位置上的ASCII码值的大小;从左往右遇到的第一个对应字符不相同时,这一对字符中,谁的ASCII码值大,对应的字符串就大,与字符串长度无关
printf("%d\n", ret);
return 0;
}
//strcmp的模拟实现
int compare_str(const char* arr1, const char* arr2)
{
while (*arr1 == *arr2)
{
if (*arr1 == 0)
return 0;
arr1++;
arr2++;
}
if (*arr1 > *arr2)
return 1;
else
return -1;
}
int main()
{
char arr1[] = "abcderf";
char arr2[] = "abcdddd";
int ret = compare_str(arr1, arr2);
//strcmp比较的是对应字符位置上的ASCII码值的大小;从左往右遇到的第一个对应字符不相同时,这一对字符中,谁的ASCII码值大,对应的字符串就大
printf("%d\n", ret);
return 0;
}
//strncpy
//char* strncpy(char* destination, const char* source, size_t num) 长度受限制、相对安全
//strncpy是把source中的前num个字符拷贝到destination中,从destination的第一个字符开始依次覆盖
//如果source的长度小于num,则拷贝完source的所有字符之后,在destination的后边继续追加0,直到够num个字符
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "hello";
strncpy(arr1, arr2, 8);
printf("%s\n", arr1); //hello
//strncpy(arr1, arr2, 3);
//printf("%s\n", arr1); //heldef
return 0;
}
//strncat
//char* strncat(char* destination, const char* source, size_t num) 长度受限制、相对安全
//strncat是从destination的'\0'开始追加(即追加第一个字符直接覆盖destination的'\0'),追加结束后会在追加后的destination最后面自动补充'\0',该'\0'不计入num
//如果num大于source的字符个数,则只追加source的全部字符,不会额外追加,但是自动补充'\0'是不变的
//可以实现自己追加自己
int main()
{
char arr1[20] = "hello ";
char arr2[] = "world";
//strncat(arr1, arr2, 3);
//printf("%s\n", arr1); //hello wor
strncat(arr1, arr2, 8);
printf("%s\n", arr1); //hello world
return 0;
}
//strncmp
//int strncmp(const char* str1, const char* str2, size_t) 长度受限制、相对安全
//strncmp与strcmp的区别只是strncmp比较的是str1和str2两个字符串的前num个字符,而strcmp比较的是两个字符串的所有字符,其余所有规则均相同发
int main()
{
char arr1[] = "abcdefg";
char arr2[] = "abcddddd";
int ret1 = strncmp(arr1, arr2, 4);
int ret2 = strncmp(arr1, arr2, 7);
printf("%d\n", ret1); //0
printf("%d\n", ret2); //1
return 0;
}
//strstr
//char* strstr(const char* str1, const char* str2)
//strstr是在字符串str1中找另一个字符串str2,返回的是str1中第一次出现str2时的地址,如果str1中找不到str2,则返回空指针(NULL),空指针用%p打印是00000000
int main()
{
char arr1[] = "abcdbcdbcdefg";
char arr2[] = "bcd";
char* s = strstr(arr1, arr2);
if (s == NULL)
printf("找不到\n");
else
printf("%s\n", s); //bcdbcdbcdefg
printf("%p\n", s); //002FFB71
return 0;
}
//strstr的模拟
char* search_str(const char* arr1, const char* arr2)
{
char* s1 = (char*)arr1;
char* s2 = NULL;
char* s3 = NULL;
while (*s1)
{
s2 = (char*)arr2;
s3 = s1;
while (*s2&&*s3&&*s2 == *s3)
{
s2++;
s3++;
}
if (*s2 == '\0')
return s1;
else
s1++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdefg";
char arr2[] = "def";
char* p = search_str(arr1, arr2);
printf("%s\n", p);
return 0;
}