字符串和内存函数
1.求字符串长度 strlen
函数声明格式:size_t strlen ( const char * str );
作用:计算字符串长度
代码:
#include<stdio.h>
#include<string.h>
//strlen以'\0'为结束标志
int main()
{
char str1[] = "abcdef";
printf("%d\n",strlen(str1));
return 0;
}
//下面是模拟实现strlen
int my_strlen(const char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "abc";
int len = my_strlen(arr);
printf("%d", len);
return 0;
}
2.长度不受限制的字符串函数 strcpy strcat strcmp
2.1 strcpy
函数声明格式: char* strcpy(char * destination, const char * source );
作用: 复制字符串
代码:
#include<stdio.h>
#include<string.h>
#include<assert.h>
//strlen以'\0'为结束标志
int main()
{
char arr1[30] = {0};
char arr2[] = "abcdef";
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
//下面是模拟实现strcpy
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = {0};
char* arr2 = "hello bit";
printf("%s\n", my_strcpy(arr1, arr2));
return 0;
}
2.2 strcat
函数声明格式: char * strcat ( char * destination, const char * source );
作用: 复制一个字符串,将这个字符串拼接在另一个字符串后面
代码:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{
char arr1[20] = "hello";
char arr2[] = " bit";
printf("%s\n", my_strcat(arr1, arr2));
return 0;
}
//下面是模拟实现strcat
char* my_strcat(char* dest, char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest)
{
dest++;
}
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "Hello ";
char arr2[] = "World";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
2.3 strcmp
函数声明格式: int strcmp ( const char * str1, const char * str2 );
作用: 比较两个字符串的大小,返回比较的结果。
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
代码:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int main()
{
char arr1[] = "abcd";
char arr2[] = "abdc";
int ret = strcmp(arr1, arr2);//是逐个比较字符所对应的ascii码值
if (ret > 0)
{
printf(">\n");
}
else if (ret == 0)
{
printf("== \n");
}
else
{
printf("<\n");
}
return 0;
}
//下面是模拟实现strcmp
int my_strcmp(const char* s1, const char* s2)
{
assert(s1 && s2);
while (*s1 == *s2)
{
if (*s1 == '\0')
{
return 0;
}
s1++;
s2++;
}
return *s1 - *s2;
}
int main()
{
char arr1[] = "abc";
char arr2[] = "abc";
int ret = my_strcmp(arr1, arr2);
if (ret > 0)
{
printf(">\n");
}
else if (ret < 0)
{
printf("<\n");
}
else
{
printf("=\n");
}
return 0;
}
3.长度受限制的字符串函数介绍 strncpy strncat strncmp
3.1 strncpy
函数声明格式:
char * strncpy ( char * destination, const char * source, size_t num );
作用: 用来复制字符串的前num个字符
代码:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "efcgq";
strncpy(arr1, arr2, 4);
printf("%s\n", arr1);
return 0;
}
3.2 strncat
函数声明格式:
char * strncat ( char * destination, const char * source, size_t num );
作用: 从字符串的开头拷贝num个字符到另一个字符串尾部
代码:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "abcdef\0XXXXXXXX";
char arr2[] = "qwe";
strncat(arr1, arr2, 3);
printf("%s\n", arr1);
return 0;
}
3.3 strncmp
函数声明格式: int strncmp ( const char * str1, const char * str2, size_t num );
作用:
用来比较s1和s2字符串的前num个字符
若str1与str2的前n个字符相同,则返回0;若str1大于str2,则返回大于0的 值;若str1 小于str2,则返回小于0的值。
代码:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcdef";
char arr2[] = "abddq";
int ret = strncmp(arr1, arr2, 4);
printf("%d\n", ret);
return 0;
}
4.字符串查找 strstr strtok
4.1 strstr
函数声明格式: char * strstr ( const char *str1, const char * str2);
作用: 返回字符串中首次出现子串的地址
返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
代码:
#include<stdio.h>
#include<string.h>
#include<assert.h>
//模拟实现strstr
char* my_strstr(char* str1, char* str2)
{
assert(str1 && str2);
char* s1 = str1;
char* s2 = str2;
char* cur = str1;
while (*cur)
{
s1 = cur;
s2 = str2;
while ((*s1 == *s2) && s1 && s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)cur;
}
cur++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdefghi";
char arr2[] = "efg";
char* ret = my_strstr(arr1, arr2);
if (NULL == ret)
{
printf("找不到子串\n");
}
else
{
printf("%s\n", ret);
}
return 0;
}
4.2 strtok
函数声明格式: char * strtok ( char * str, const char * sep );
作用: 用来将字符串分割成一个个片段
返回值: 从str开头开始的一个个被分割的串。当str中的字符查找到末尾时,返回NULL。如果查找不到sep中的字符时,返回当前strtok的字符串的指针。
所有sep中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。
#include <stdio.h>
#include<string.h>
int main()
{
char *p = "zhangwei@tedu.tech";
const char* sep = ".@";
char arr[30];
char *str = NULL;
strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容
for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep))
{
printf("%s\n", str);
}
}
5.错误信息报告 strerror
函数声明格式: char * strerror ( int errnum );
作用: 获取系统错误信息或打印用户程序错误信息。
#include <limits.h>
#include <errno.h>
#include<stdio.h>
int main()
{
int* p = (int*)malloc(INT_MAX);//想堆区申请内存的
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
return 0;
}
6.字符操作
函数 如果他的参数符合下列条件就返回真
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂 直制表符’\v’
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母a~~f,大写字母A~F
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母a–z或A~Z
isalnum 字母或者数字,a~z, A~Z, 0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符
7.内存操作函数 memcpy memmove memset memcmp
7.1 memcpy
函数声明格式:
void * memcpy ( void * destination, const void * source, size_t num );
作用: 由source指向地址为起始地址的连续n个字节的数据复制到destination指向地址为起始地址的空间内
#include<stdio.h>
#include<string.h>
#include<assert.h>
//模拟实现memcpy
void* my_memcpy(void* dest, const void* src, size_t count)
{
assert(dest && src);
void* ret = dest;
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[5] = { 0 };
my_memcpy(arr2, arr1, 20);//20是字节
int i;
for (i = 0; i < 5; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
7.2 memmove
函数声明格式:
void* memmove(void* destination, const void* source, size_t num);
作用: 拷贝一定长度的内存的内容
代码:
#include<stdio.h>
#include<string.h>
#include<assert.h>
//模拟实现memmove
void* my_memmove(void* dest, const void* src, size_t count)
{
void* ret = dest;
assert(dest && src);
if (dest < src)//从前往后覆盖
{
while (count--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else//从后往前覆盖
{
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10};
my_memmove(arr1 + 2, arr1, 20);//20是字节数
int i;
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
7.3 memset
函数声明格式: void* memset(void *s, int ch, size_t n);
作用: 在一段内存块中填充某个给定的值,将s中当前位置后面的n个字节用 ch 替换并返回 s
代码:
#include <string.h>
#include <stdio.h>
int main(void)
{
char arr[]="Helloworld\n";
memset(arr+2,'*',strlen(arr));
printf("%s\n",arr);
return 0;
}
7.4 memcmp
函数声明格式: int memcmp(const void *str1, const void *str2, size_t n);
作用: 把存储区 str1 和存储区 str2 的前 n 个字节进行比较
返回值:
如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str2 小于 str1。
如果返回值 = 0,则表示 str1 等于 str2。
代码:
#include<string.h>
#include<stdio.h>
int main()
{
char *s1 = "Hello,Programmers!";
char *s2 = "Hello,Programmers!";
int r;
r = memcmp(s1,s2,strlen(s1));
if(!r)
printf("s1 and s2 are identical\n");//s1等于s2
elseif(r<0)
printf("s1 is less than s2\n");//s1小于s2
else
printf("s1 is greater than s2\n");//s1大于s2
return 0;
}