简介
string .h 头文件定义了一个变量类型、一个宏和各种操作字符数组的函数。
库变量
下面是头文件 string.h 中定义的变量类型:
序号 | 变量 & 描述 |
1 | size_t 这是无符号整数类型,它是 sizeof 关键字的结果。 |
库宏
下面是头文件 string.h 中定义的宏:
序号 | 宏 & 描述 |
1 | NULL 这个宏是一个空指针常量的值。 |
库函数
下面是头文件 string.h 中定义的函数:
实现函数
#include<assert.h>
//-----------------------------------------------------------------------------------
char* my_strcpy(char* dest, const char* src) {
assert(dest != NULL);
assert(src);
char* ret = dest;
while (*dest++ = *src++) ;
return ret;
}
//-----------------------------------------------------------------------------------
//strcat不能给自己追加(用strncat)
char* my_strcat(char* dest,const char* scr) {
assert(dest && scr);
char* set = dest;
while (*dest)
dest++;
while (*dest++ = *scr++) ;
return set;
}
//-----------------------------------------------------------------------------------
//srtcpy复制时不管是否越界都复制
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (!*str1)
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
//-----------------------------------------------------------------------------------
//strncpy多的字节数用’\0'补齐
char* my_strncpy(char* dest, const char* scr, unsigned int count)
{
assert(dest && scr);
char* set = dest;
while (count && (*dest++ = *scr++))
count--;
if (count)
while (--count)
*dest++ = '\0';
return set;
}
//----------------------------------------------------------------------------------
//strncat多的字节数只补一个‘\0’
char* my_strncat(char* dest, const char* scr, unsigned int count)
{
assert(dest && scr);
char* set = dest;
while (*dest)
dest++;
while (count--)
if ((*dest++ = *scr++) == '\0')
return set;
*dest = '\0';
return set;
}
//-----------------------------------------------------------------------------------
//1.strlen递归
int my_strlen(const char* dest)
{
if (*dest++)
return 1 + my_strlen(dest);
else
return 0;
}
//2.strlen计数器
int my_strlen_2(const char* dest)
{
int count = 0;
while (*dest++)
count++;
return count;
}
//3.指针-指针
int my_strlen_3(const char* dest)
{
char* tmp = (char*) dest;
while (*dest++)
;
return dest - tmp - 1;
}
//------------------------------------------------------------------------------------
//1.strstr经典
char* my_strstr(const char* p1, const char* p2)
{
assert(p1 && p2);
char* s1 = NULL, * s2 = NULL, * cur = (char*)p1;
if (!*p2)//(*p2 == '\0')
return (char*)p1;
while(*cur)
{
s1 = cur;
s2 = (char*)p2;
while (!(*s1-*s2) && *s1 && *s2)//((*s1 == *s2) && (*s1!='\0') && (*s2!='\0'))
{
s1++;
s2++;
}
if (!*s2)//(*s2 == '\0')
return cur;
if (!*s1)
return NULL;
cur++;
}
return NULL;
}
//2.strstr的KMP算法
char* my_strstr_KMP(const char* p1, const char* p2)
{
assert(p1 && p2);
//对字串p2生成next数组
int* next = (int*)malloc(strlen(p2) *sizeof(int));
next[0] = 0;
next[1] = 0;
char* i = (char*)p2;//前缀
char* j = (char*)p2+1;//后缀
int com = 0;//匹配个数
int k = 2; //下标
while (*j)
{
if ((*(i + com) == *j)&&((i + com) < (j - com))) //
com++;
else
{
if(com!=0)
com = next[com-1];
if (*(i + com) == *j)
com++;
}
next[k] = com;
k++;
j++;
}
//代码主体
char* s1 = (char*)p1;
char* s2 = (char*)p2;
char* ret = (char*)p1;
while (*s1)
{
if (!(*s1 - *s2))//*s1==*s2
{
s1++;
s2++;
}
else
{
s2 = (char*)p2+next[s1-ret+1];
ret = s1;
}
if (!*s2)
return ret;
}
return NULL;
}
//------------------------------------------------------------------------------------
void* my_memcpy(void* dest, const void* src, unsigned int num)
{
assert(dest && src);
void* ret = dest;
while (num--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
return ret;
//------------------------------------------------------------------------------------
void* my_memmove(void* dest, const void* scr, unsigned int num)
{
assert(dest && scr);
void* ret = dest;
if (dest < scr)//前->后
while (num--)
{
*(char*)dest = *(char*)scr;
++(char*)dest;
++(char*)scr;
}
else//后->前
while (num--)
*((char*)dest+num) = *((char*)scr+num);
return ret;
}
用例
//strtok的使用,分割字符
#include<stdio.h>
#include<string.h>
int main()
{
arr4[25]="165.354.156@456";
char tmp1[25] = { 0 };
char* p = "@.";
strcpy(tmp1, arr4);
printf("%s\n", strtok(tmp1, p));
printf("%s\n", strtok(NULL, p));
printf("%s\n", strtok(NULL, p));
printf("%s\n", strtok(NULL, p));
char tmp2[25] = { 0 };
strcpy(tmp2, arr4);
char* set = NULL;
for (set = strtok(tmp2, p); set != NULL; set = strtok(NULL, p))
printf("%s\n", set);
return 0;
}
//strerror使用,将错误码转化为对应的字符串
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main
{
printf("%s\n", strerror(0));//No error
printf("%s\n", strerror(1));//Operation not permitted
printf("%s\n", strerror(2));//No such file or directory
// ... ... 还有很多其他错误码
FILE* fp = fopen("text.txt", "r");
if (fp == NULL)
printf("%s\n", strerror(errno));//errno头文件为<errno.h>,是发生错误时自动生成的全局变量
else
printf("open file success");
return 0;
}
//memcpy处理不重叠内存拷贝(但有的编译器可以拷贝重叠)
//memmove处理重叠内存拷贝
//如果dest与scr数据地址交叉时会出错,应该用memmove
#include<string.h>
#include<stdio.h>
int main()
{
int arr[25] = { 1,2,3,4,5,6,7,8,9 }, tmp[25];
memcpy(tmp, arr,sizeof(arr));
memcpy(tmp + 2, tmp, 4*4);
//用1,2,3,4替换3,4,5,6
for (int i = 0; i < 9; i++)
printf("%d ", tmp[i]);
//预期为1 2 1 2 3 4 7 8 9
//结果为1 2 1 2 1 2 7 8 9
memcpy(tmp, arr, sizeof(arr));
memmove(tmp + 2, tmp, 4);
for (int i = 0; i < 9; i++)
printf("%d ", tmp[i]);
//结果为1 2 1 2 3 4 7 8 9
return 0;
}
//memcmp使用
#include<string.h>
#include<stdio.h>
int main()
{
int arr1[15] = { 0,1,2,3,4 };
int arr2[15] = { 0,1,2,4,5 };
printf("%d\n", memcmp(arr1, arr2, 3 * 4)); //0
printf("%d\n", memcmp(arr1, arr2, 3 * 4 + 1)); //-1
printf("%d\n", memcmp(arr2, arr1, 3 * 4 + 1)); //1
return 0;
}
#include<string.h>
#include<stdio.h>
int main()
{
//正确用法
char arr1[10];
memset(arr1, '#', sizeof(arr1));
for (int i = 0; i < 10; i++)
printf("%c", arr1[i]);
printf("\n");
//错误用法
int arr2[10];
memset(arr2, 1, sizeof(arr2));
for (int i = 0; i < 10; i++)
printf("%d ", arr2[i]);
//内存相关区域为 01 01 01 01(16进制)=16843009
return 0.;
}