头文件:#include <string.h>
看过上一篇的小伙伴们都知道,对于下列函数应该都有所了解.
strcpy函数:.拷贝字符串函数 strcat函数:.追加字符函数 strcmp函数:.字符串拷贝函数
这些函数在使用时,都是遇到’\0’,才停止他们的拷贝,追加,比较等操作 如果我们想要只操作其中的部分,就可以增加一个参数来实现. 由于功能参数等与前面的函数相似,本篇不做重点讲解.
拷贝num个字符从源字符串到目标空间
追加num个源字符到目标空间
比较两个字符串的前num个字符,返回值与strcmp一致.
char * strncpy ( 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 );
增加一个size_t 类型的参数num,用于限定原来的函数.
#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* strDest, const char* strSource, size_t count)
{
assert(strDest);
assert(strSource);
char* ret = strDest;
while (count--)
{
*strDest++ = *strSource++;
}
return ret;
}
int main()
{
char arr1[20] = "xxxxxxxxxxxxxx";
char arr2[] = "Hello CSDN!";
int sz2 = sizeof(arr2) / sizeof(arr2[0]);
printf("%s", my_strncpy(arr1,arr2,5));
return 0;
}
运行结果:
Helloxxxxxxxxx
注意:
1.strncpy只拷贝num个字符,并不会额外附加’\0’字符. 2.如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个. 这个在模拟的时候并没有添加上去.
#include <stdio.h>
#include <assert.h>
char* my_strncat(char* destination, const char* source, size_t num)
{
assert(destination);
assert(source);
char* ret = destination;
while (*destination != '\0')
{
destination++;
}
while (num--)
{
*destination++ = *source++;
}
return ret;
}
int main()
{
char arr1[20] = "Hello ";
char arr2[] = "CSDN!";
int sz2 = sizeof(arr2) / sizeof(arr2[0]);
printf("%s", my_strncat(arr1, arr2, 3));
return 0;
}
运行结果:
Hello CSD
#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* str1, const char* str2, size_t num)
{
while (num--)
{
if (*str1 > *str2)
{
return 1;
}
else if (*str1 < *str2)
{
return -1;
}
str1++;
str2++;
}
return 0;
}
int main()
{
char arr1[20] = "aabbccdd";
char arr2[] = "aabbcdef";
int sz2 = sizeof(arr2) / sizeof(arr2[0]);
printf("%d", my_strncmp(arr1, arr2, 5));
return 0;
}
运行结果:
0
解释: 因为前5个字符相同,num个字符比较结束,认为是相同字符串.
头文件:#include <string.h>
用于查找主字符串中是否包含子字符串.包含返回第一次匹配成功的字符首地址.不包含则返回NULL.
力扣------找出字符串中第一个匹配的下标. 通过strstr函数找到第一个匹配的字符指针,
该指针-字符串首地址指针=该字符的下标.
int strStr(char * haystack, char * needle){
char*ret=strstr(haystack,needle);
if(ret-haystack<0)//小于0时,返回-1;
{
return -1;
}
return ret-haystack;
}
代码实现:
#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
if (*str2 == '\0')//如果子字符串是空字符串,直接返回主字符串
{
return str1;
}
const char *ret,*p1,*p2;
ret = p1 = str1;
p2 = str2;
while (*p1&&*p2)//循环停止条件为主字符串或者子字符串有一个为空
{
if (*p1 == *p2)//相等则继续比较
{
p1++;
p2++;
}
else//不相等则返回指定位置重新比较
{
p1 = ++ret;
p2 = str2;
}
}
if (*p2 == '\0')//如果子字符串比较结束,则匹配成功
{
return ret;
}
else//否则匹配失败
return NULL;
}
int main()
{
char str1[20] = "ABBCDABBACBBD";
char str2[] = "ABBA";
char* ret = my_strstr(str1, str2);
if (ret == NULL)
{
printf("没有找到\n");
}
else printf("%s", ret);
}
ABBACBBD
strtok函数 头文件:#include <string.h>
将字符串str根据delimiters 中的字符进行分割.
参数介绍:
参数 | 意义 |
---|---|
str | 需要被分隔的字符串(第一次传参的时候),传入NULL指针时,会从上一次修改的地址处 |
delimiters | 定义了用作分隔符的字符集合 |
#include <stdio.h>
#include <string.h>
int main()
{
char str1[30] = "123.456.789_111,222@333";
char str2[30];
char a[] = "._,@";
strcpy(str2, str1);//因为strtok函数会改变传过去的字符串的内容,所以我们是将备份传过去
char* ret;
//除了第一次调用时第一个参数为str2以外,后面的调用都是传入NULL,这样才会继续向后寻找标记分隔字符.
for (ret = strtok(str2, a); ret != NULL; ret = strtok(NULL, a))
{
printf("%s\n", ret);
}
return 0;
}
运行结果:
123 456 789 111 222 333
strtok函数并不是一次就将字符串中的所有分隔字符改为’\0’,而是调用它一次,修改一个. strtok函数第一次调用时,会找到str中的第一个分隔符标记,并将其用 \0 结尾,然后返回一个指向这个标记的指针。 strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。:
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。 strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果后面已经没有标记分隔,则返回 NULL 指针.
库函数在使用错误时,会返回一串数字,这些数字就是错误码. strerror函数用于返回错误码对应的错误信息.
例如:
#include <stdio.h>
#include <string.h>
int main()
{
printf("%s\n", strerror(0));
printf("%s\n", strerror(1));
printf("%s\n", strerror(2));
printf("%s\n", strerror(3));
printf("%s\n", strerror(4));
printf("%s\n", strerror(5));
return 0;
}
No error Operation not permitted No such file or directory No such process Interrupted function call Input/output error
但是strerror函数并不是这样使用的,因为我们也不知道错误码是什么,像上面这种是属于提前预判了的. 在库函数执行错误后,会将错误码存放在一个error的变量中.所以一般strerror函数是这样使用的.
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
//打开文件
FILE* pf = fopen("CSDN.txt", "r");
if (pf == NULL)
{
//printf("%s\n", strerror(errno));
perror("fopen");
return 1;
}
//关闭文件
fclose(pf);
pf = NULL;//避免空指针
return 0;
}
perror函数等价于printf(“%s\n”, strerror(errno)); 即strerror函数是返回指向错误信息的字符串地址,而perror函数是将错误信息直接打印出来.
希望这篇文章能帮助大家对c语言中的库函数有关字符函数和字符串函数有更深层的理解. 今天就先到这里啦!!!