乐观学习,乐观生活,才能不断前进啊!!!
我的主页:optimistic_chen
我的专栏:c语言
点击主页:optimistic_chen和专栏:c语言,
创作不易,大佬们点赞鼓励下吧~
前言:
长度不受限制的字符串函数-strcpy,strcat,strcmp
长度受限制的字符串函数-strncpy,strncat,strncmp
文章目录
- 1.strlen函数(计算字符串长度)
- 2. strcpy函数(拷贝字符串)
- 3.strcat函数(字符串追加)
- 4.strcmp函数(两个字符串比较)
- 5.strncpy函数(有限制的拷贝字符串)
- 6.strncat函数(有限制的追加字符串)
- 7. strncmp函数(有限制比较字符串)
- 8.strstr函数(查找相同的字符串)
- 9.strtok函数(分割字符串)
- 10.strerror函数(打印错误信息)
- 完结
1.strlen函数(计算字符串长度)
总结:
• 字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯ 出现的字符个数(不包含 ‘\0’ )。
• 参数指向的字符串必须要以 ‘\0’ 结束。
• 注意函数的返回值为size_t,是⽆符号的( 易错 )
• strlen的使⽤需要包含头⽂件#include<string.h>
直接使用库函数:
/* strlen example */
#include <stdio.h>
#include <string.h>
int main ()
{
char szInput[256];
printf ("Enter a sentence: ");
gets (szInput);
printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));
return 0;
}
自主模拟:
test 1:
//计数器⽅式
int my_strlen(const char * arr)
{
int count = 0;
assert(arr);//断言确定字符串不为空
while(*arr)
{
count++;
arr++;
}
return count;
}
test 2:
//递归解决问题
int my_strlen(const char * arr)
{
assert(arr);//断言确定字符串不为空
if(*arr == '\0')
return 0;
else
return 1+my_strlen(arr+1);
}
test 3:
//指针-指针的⽅式
int my_strlen(char *s)
{
assert(arr);
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;//指针之间的大小==字符串个数
}
2. strcpy函数(拷贝字符串)
总结:
• 源字符串必须以 ‘\0’ 结束。
• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间。
• ⽬标空间必须⾜够⼤以确保能存放源字符串。
• ⽬标空间必须可修改。
直接使用库函数
/* strcpy example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]="Sample string";
char str2[40];
char str3[40];
strcpy (str2,str1);
strcpy (str3,"copy successful");
printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
return 0;
}
自主模拟
test 1:
my_strcpy(char* dest, char* src)
{
while (*src != '\0')
{
*dest++ = *src++;
}
*dest = *src;
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
test 2:
char *my_strcpy(char *dest, const char*src)
{
char *ret = dest;
assert(dest != NULL);
assert(src != NULL);
while((*dest++ = *src++))
{
;
}
return ret;//返回目的地
}
3.strcat函数(字符串追加)
总结:
• 源字符串必须以 ‘\0’ 结束。
• ⽬标字符串中也得有‘\0’ ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。
直接使用库函数
/* strcat example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}
自主模拟
test 1:
char* my_strcat(char* dest,const char* src)
{
char ret = dest;
while (*dest != '\0')
{
dest++;
}
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[30] = "hello ";
char arr2[30] = "reader";
my_strcat(arr1, arr2);
printf("%s", arr1);
}
4.strcmp函数(两个字符串比较)
总结:
◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字
◦ 第⼀个字符串等于第⼆个字符串,则返回0
◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
◦ 那么如何判断两个字符串? ⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩。
直接使用库函数
#include <stdio.h>
#include <string.h>
int main ()
{
char key[] = "apple";
char buffer[80];
do {
printf ("Guess my favorite fruit? ");
fflush (stdout);
scanf ("%79s",buffer);
} while (strcmp (key,buffer) != 0);
puts ("Correct answer!");
return 0;
}
自主模拟
test 1:
int my_strcmp(char* str1, char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
if (*str1 > *str2)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
char arr1[] = "abd";
char arr2[] = "acfed";
int ret = my_strcmp(arr1, arr2);
printf("%d", ret);
return 0;
}
5.strncpy函数(有限制的拷贝字符串)
总结:
• 拷⻉num个字符从源字符串到⽬标空间。
• 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。
直接使用库函数
/* strncpy example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]= "To be or not to be";
char str2[40];
char str3[40];
/* copy to sized buffer (overflow safe): */
strncpy ( str2, str1, sizeof(str2) );
/* partial copy (only 5 chars): */
strncpy ( str3, str2, 5 );
str3[5] = '\0'; /* null character manually added */
puts (str1);
puts (str2);
puts (str3);
return 0;
}
自主模拟
test 1:
char* my_strncpy( char* dest,const char* src, int n)
{
int i = 0;
for (i = 0; src[i] != '\0'&&i<n; i++)
{
dest[i] = src[i];
}
dest[i] = '\0';
return dest;
}
int main()
{
char dest[100] = "acdef";
char* src = "acd";
char* ret=my_strncpy(dest, src, 3);
printf("%s", ret);
return 0;
}
6.strncat函数(有限制的追加字符串)
总结:
•将source指向字符串的前num个字符追加到destination指向的字符串末尾,追加⼀个 \0 字符
•如果source指向的字符串的⻓度⼩于num的时候,只会将字符串中到\0 的内容追加到destination指向的字符串末尾
直接使用库函数
#include <stdio.h>
#include <string.h>
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;
}
自主模拟
test 1:
char* my_strncat(char* dest, char* src, size_t num)
{
char ret = dest;
while (*dest != '\0')
{
dest++;
}
while (num&&(*dest++ = *src++)!='\0')
{
num--;
}
*dest = '\0';//追加结束后结尾
return ret;
}
int main()
{
char arr1[20] = "hello ";
char arr2[20] = "reader";
my_strncat(arr1, arr2, 4);
printf("%s", arr1);
return 0;
}
实现结果:
7. strncmp函数(有限制比较字符串)
总结:
⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟
如果提前发现不⼀样,就提前结束,⼤的字符所在的字符串⼤于另外个。
如果num个字符都相等,就是相等返回0.
直接使用库函数
#include <stdio.h>
#include <string.h>
int main ()
{
char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
int n;
puts ("Looking for R2 astromech droids...");
for (n=0 ; n<3 ; n++)
if (strncmp (str[n],"R2xx",2) == 0)
{
printf ("found %s\n",str[n]);
}
return 0;
}
自主模拟
test 1:
int my_strncmp(char* str1, char* str2,size_t num)
{
int ret = 0;
while (num--!=0)
{
ret = *str1 - *str2;
if (*str1 == '\0')
{
return 0;
}
str1++;
str2++;
}
return ret;
}
int main()
{
char arr1[] = "apple";
char arr2[] = "acpbe";
int ret = my_strncmp(arr1, arr2, 4);
printf("%d", ret);
return 0;
}
8.strstr函数(查找相同的字符串)
总结:
函数返回字符串str2在字符串str1中第⼀次出现的位置
字符串的⽐较匹配不包含 \0 字符,以 \0 作为结束标志
直接使用库函数
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="This is a simple string";
char * pch;
pch = strstr (str,"simple");
if (pch != NULL)
strncpy (pch,"sample",6);
puts (str);
return 0;
}
自主模拟
test 1:
char* my_strstr(char* str1, char* str2)
{
const char* s1 = NULL;
const char* s2 = NULL;
const char* sta = str1;
if (*str2 == '\0')
{
return (char*)str1;
}
while (*sta)
{
s1 = sta;
s2 = str2;
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
return (char*)sta;
sta++;
}
return NULL;
}
int main()
{
char arr1[] = "acdefgh";
char arr2[] = "fgh";
char* ret = my_strstr(arr1, arr2);
if (ret == NULL)
{
printf("找不到\n");
}
else
{
printf("%s", ret);
}
return 0;
}
9.strtok函数(分割字符串)
总结:
• sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合
• 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记。
• strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容并且可修改。)
• strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。
• strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。
• 如果字符串中不存在更多的标记,则返回 NULL 指针。
直接使用库函数
int main()
{
char arr[] = "[email protected]";
char arr2[30] = { 0 };
strcpy(arr2,arr);
const char* sep = "@.";
char* ret = NULL;
for (ret = strtok(arr, sep); ret != NULL; ret = strtok(NULL, sep))
{
printf("%s\n",ret);
}
return 0;
}
10.strerror函数(打印错误信息)
直接使用库函数
#include <stdio.h>
#include <string.h>
#include <errno.h>//注意头文件
int main ()
{
FILE * pFile;
pFile = fopen ("unexist.ent","r");
if (pFile == NULL)
printf ("Error opening file unexist.ent: %s\n",strerror(errno));
return 0;
}
完结
本次博客到此结束,博主认为大家需要熟练掌握前8种函数,能够独立自主实现函数。
最后觉得博客有帮助,可以点点关注,支持一下,期待下次博客~~~