目录
先介绍字符串函数以及内存函数有哪些:
1,求字符串长度:
2,长度不受限制的字符串函数:
3,字符串受限制的函数:
4,字符串查找
5,错误信息报告:
6,字符操作:
7,内存操作函数
求字符串长度:
strlen():不计算"\0",计算到‘\0’为止
strlen()返回值为无符号数(易错)
因为无符号数 - 无符号数得到的结果还是无符号数
int main()
{
unsigned int a = 4;
unsigned int b = 8;
if (a - b > 0)
{
printf("a - b > 0\n");
printf("%d\n", a - b);
printf("%u\n", a - b);
}
else
{
printf("a - b < 0\n");
}
return 0;
}
长度不受限制的字符串函数:
strcpy
strcat
strcmp
strcpy():字符串复制函数
char* strcpy (char* destination,const char* score);
int main()
{
char arr[20] = "##########";
//arr = "hello"; //err
strcpy(arr, "hello"); //right
//根据内存调试,可以看到’\0‘也会被复制;而且也必须复制
//这个函数最好仅限字符串使用,而且要保证目标的空间足够大,可以存放源字符串的数据
//当然目标字符串不可以是常量字符串(因为常量字符串不可以修改)
printf("%s\n", arr);
return 0;
}
//输出
hello
strcat()字符串追加(连接)函数
char* strcpy (char* destination,const char* score);
char* my_strcat(char* dest, const char* sc)
{
char* ret = dest;
assert(dest&& sc);
//1,找到目标字符串中的\0
while (*dest)
{
dest++;
}
while (*dest++ = *sc++)
{
;
}
return ret;
}
int main()
{
char ch1[20] = "hello ";
char ch2[] = "world";
strcat(ch1, ch2);
printf("%s\n", ch1);
printf("%s\n", my_strcat(ch1, ch2));
return 0;
}
//输出
hello world
hello worldworld
目标字符串空间足够;只作用于字符串('\0'也会被复制过去);
原字符串和目标字符串都必须有’\0‘;
strcmp()字符串比较函数
自己实现strcmp
int my_strcmp(const char* p1, const char* p2)
{
assert(p1 && p2);
while (*p1 == *p2)
{
if (*p1 == '\0')
{
return 0;
}
p1++;
p2++;
}
//if (*p1 > *p2)
//{
// return 1;
//}
//else
//{
// return -1;
//}
return *p1 - *p2;
}
int main()
{
char* p1 = "abc";
char* p2 = "aabb";
printf("%d\n", my_strcmp(p1, p2));
printf("%d\n", strcmp(p1, p2));
if (strcmp(p1, p2) == 0)
{
printf("相等\n");
}
else if (strcmp(p1, p2) < 0)
{
printf("p1<p2\n");
}
else
{
printf("p1>p2\n");
}
return 0;
}
字符串受限制的函数:
strncpy
strncat
strncmp
后面追加一个int num;这个数字表示从源字符串复制,添加,比较0-num个
strstr() -- 字符串查找
strstr(str1,str2);
在字符串str1里查找字符串str2是否存在
char * strstr(const char* ,const char*);
char* my_strstr(const char* p1, const char* p2)
{
assert(p1 && p2);
const char* flag = p1;
const char* s1 = NULL;
const char* s2 = NULL;
if (*p2 == '\0')
{
return p1;
}
while (*flag)
{
s1 = flag;
s2 = p2;
while (*s1 && *s2 && (*s1 == *s2))
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return flag;
}
else
{
flag++;
}
}
return NULL;
}
int main()
{
//char ch1[] = "abcdef";
char ch1[] = "abbabcdefbbc";
//char ch2[] = "bcd";
char ch2[] = "bbc";
//char* ret = strstr(ch1, ch2);
char* ret = my_strstr(ch1, ch2);
if (ret == NULL)
{
printf("没找到!\n");
}
else
{
printf("找到了!\n");
}
return 0;
}
//输出
找到了!
KMP算法 - 字符串查找算法
strtok()函数 - 切割字符串
192.168.3.122
198 168 3 122
char* strtok(char*str,const char*sep)
int main()
{
char ch[] = "mhq@qq.com.mhq@qq.com";
char* p = ".@" ;
//printf("%s\n",strtok(ch, p));
//printf("%s\n",strtok(NULL, "@."));
char temp[200] = { 0 };
strcpy(temp, ch);
char* ret = NULL;
for (ret = strtok(ch, p); ret != NULL; ret = strtok(NULL, p))
{
printf("%s\n", ret);
}
return 0;
}
//输出
mhq
qq
com
mhq
qq
com
strtok()函数会更改字符串,所以一般都是使用看临时拷贝且可修改的字符串;
每次使用sttok()函数,都会记住这个函数的标记符的位置
这个函数没有进行模拟实现
错误信息报告:
// strerror()函数
使用库函数的时候,都会设置错误码,把错误码转换为错误信息
全局错误码:int errno ;//5
int main()
{
//printf("0:%s\n", strerror(0));
//printf("1:%s\n", strerror(1));
//printf("2:%s\n", strerror(2));
//printf("3:%s\n", strerror(3));
//printf("4:%s\n", strerror(4));
//printf("5:%s\n", strerror(5));
//printf("6:%s\n", strerror(6));
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
//printf("%s\n", strerror(errno));
perror("");
perror("fopen");
return 1;
}
fclose(pf);
pf = NULL;
return 0;
}
//输出
No such file or directory
fopen: No such file or directory
创建了text.txt就不会显示错误码
perror()函数:用来打印错误信息的函数
字符操作:
isdigit()
z字符分类函数:判断参数是否为真
int main()
{
char ch = '1';
int ret = isdigit(ch);
printf("%d\n",isdigit(ch));
//如果是数字字符返回4,如果不是返回0;
printf("a:%d\n", islower('a'));
//如果是数字字符返回2,如果不是返回0;
return 0;
}
判断是你需要的字符,就返回非0;不是需要的,就返回0;
字符转换函数
isupper()
int main()
{
char ch[20] = { 0 };
scanf("%s", ch);
int i = 0;
while (ch[i] != '\0')
{
if (isupper(ch[i]))
{
ch[i] = towlower(ch[i]);
}
else
{
ch[i] = towupper(ch[i]);
}
i++;
}
printf("%s\n", ch);
return 0;
}
内存操作函数
memcpy()
memmove()
memcmp()
memset()
memcpy - 内存拷贝
void*memcpy(void *destination,const void*source,size_t num);
返回值为目标地址
注意:num表示复制的字节个数,也就是最小地址单位。
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest && src);
int i = 0;
for (i = 0; i < num; i++)
{
//*((char*)dest+i) = *((char*)src + i);
*((char*)dest)++ = *((char*)src)++;
}
return dest;
}
int main()
{
int arr1[10] = { 1,2,3,11111111,5,6,7,8,9,10 };
int arr2[20] = { 1,2 };
//memcpy(arr2, arr1, 13);
printf("%p\n",arr2);
printf("%p\n",my_memcpy(arr2, arr1, 13));
return 0;
}
memcpy()函数应该拷贝不重叠的内存
memmove()
memmove()可以处理内存重叠的情况
void*memmove(void *destination,const void*source,size_t num);
void* my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
int i = 0;
//可以把源数据从前向后拷贝,也可以从后向前拷贝
if (dest > src)
{
//从后向前拷贝
//for (i = 0; i < num; i++)
//{
// *((char*)dest + num -1- i) = *((char*)src + num -1- i);
//}
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
else if (dest < src)
{
//从前向后拷贝
for (i = 0; i < num; i++)
{
*((char*)dest+i) = *((char*)src + i);
//*((char*)dest)++ = *((char*)src)++;
}
}
else
{
;
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,11111111,5,6,7,8,9,10 };
int arr2[20] = { 1,2 };
//memcpy(arr2, arr1, 13);
printf("%p\n", arr1);
//printf("%p\n", memmove(arr1 + 2, arr1, 20));
//printf("%p\n", my_memmove(arr1 + 2, arr1, 20));
printf("%p\n", my_memmove(arr1, arr1 + 2, 20));
return 0;
}
memcpy - 只要实现了不重叠就可以了,而VS中的实现既可以拷贝不重叠,也可以拷贝重叠内存
memecmp()函数 - 内存比较
memcmp()和strcmp()很像
int main()
{
float arr1[] = { 1.0,2.0,3.0,4.0 };
float arr2[] = { 1.0,3.0 };
printf("%d\n", memcmp(arr1, arr2, 4));
printf("%d\n", memcmp(arr1, arr2, 8));
return 0;
}
memset() - 内存设置函数
void *memset(void*ptr,int value,size_t num);
函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
int main()
{
int arr[10] = { 0 };
int i = 0;
memset(arr, 255, 20);
for(i = 0;i<10;i++)
{
printf("%x\n", *(arr+i));
}
return 0;
}
输出
ffffffff
ffffffff
ffffffff
ffffffff
ffffffff
0
0
0
0
0
对于void *memset(void* ptr , int value , size_t num);
memset把每一个字节都用value来代替
//memset()只能对字符类型进行操作