字符串函数、字符函数和内存操作函数
一、字符串函数
1. strlen—求字符串长度
注意:(1)strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包
含 ‘\0’)
(2)注意函数的返回值为size_t,是无符号的
使用:
int main()
{
char arr[] = "abcdef";
printf("%d\n", strlen(arr));
return 0;
}
模拟实现:
int my_strlen(const char* p)
{
int count = 0;
while (*p)
{
p++;
count++;
}
return count;
}
int main()
{
char arr[] = "abcdefg";
int ret = my_strlen(arr);
printf("%d\n", ret);
return 0;
}
2. strcpy—拷贝字符串
(1)源字符串必须以 ‘\0’ 结束;
(2)会将源字符串中的 ‘\0’ 拷贝到目标空间
(3)目标空间必须足够大,以确保能存放源字符串
将arr2字符串的内容拷贝到arr1上;
int main()
{
char arr1[] = "abcd";
char arr2[] = "dcba";
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
模拟实现
void my_strcpy(char* dest, char* src)
{
while (*dest)
{
*dest = *src;
dest++;
src++;
}
}
int main()
{
char arr1[] = "abcd";
char arr2[] = "dcba";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
3. strcat—追加字符串
(1)源字符串必须以 ‘\0’ 结束
(2)目标空间必须有足够的大,能容纳下源字符串的内容
(3)目标空间必须可修改
使用:
int main()
{
char arr1[30] = "abcd";
char arr2[] = "efg";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
模拟实现:
char* my_strcat(char* dest, char* src)
{
char* ret = dest;
//找目标空间的' 0 '
while (*dest)
{
dest++;
}
//拷贝
while (*src)
{
*dest = *src;
dest++;
src++;
}
return ret;
}
int main()
{
char arr1[30] = "abcd";
char arr2[] = "efg";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
4. strcmp—字符串比较
一个字符一个字符比较,遇到哪个字符大,哪个字符串就大;
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
使用:
int main()
{
char arr1[] = "abcd";
char arr2[] = "abcf";
printf("%d\n", strcmp(arr1, arr2));
return 0;
}
模拟实现:
int my_strcmp(char* ptr1, char* ptr2)
{
while (*ptr1 == *ptr2)
{
if (*ptr1 == '\0')
return 0;
ptr1++;
ptr2++;
}
return *ptr1 - *ptr2;
}
int main()
{
char arr1[] = "ascfsdd";
char arr2[] = "ascf";
int ret = my_strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
5. strncpy—拷贝n个字符
拷贝n个字符从源字符串到目标空间。
如果源字符串的长度小于n,则拷贝完源字符串之后,在目标的后边追加0,直到n个。
使用:
int main()
{
char arr1[] = "hello";
char arr2[] = "xxx";
strncpy(arr1, arr2, 2);
printf("%s\n", arr1); //xxllo
return 0;
}
6. strncat—追加n个字符
使用:
int main()
{
char arr1[10] = "hello";
char arr2[] = "xxx";
strncat(arr1, arr2, 3);
printf("%s\n", arr1); //helloxxx
return 0;
}
7. strncmp—比较n个字符
比较到出现另个字符不一样或者一个字符串结束或者n个字符全部比较完.
比较前三个字符,arr1大返回大于0的数;arr1=arr2返回0;arr1小返回小于0的数;
使用:
int main()
{
char arr1[10] = "hello";
char arr2[] = "hex";
printf("%d\n", strncmp(arr1, arr2, 3));
return 0;
}
8. strstr—截断字符串
char * strstr ( const char *str1, const char * str2);
在str1中找到str2第一次出现的位置,并返回这个位置;
使用:
int main()
{
char arr1[] = "I am a student.";
char arr2[] = "a";
printf("%s\n", strstr(arr1, arr2)); //am a student
return 0;
}
模拟实现:
char* my_strstr(char* str1, char* str2)
{
char* p1 = NULL;
char* p2 = NULL;
char* cp = str1;
//当cp不等于0,即目标字符串还没找完,继续找
while (*cp)
{
//每次从cp这个位置开始往后匹配
p1 = cp;
p2 = str2;
while (*p1 && *p2 && *p1 == *p2)
{
p1++;
p2++;
}
//当匹配完字符
if (*p2 == '\0')
return cp;
//只要从这个cp开始往后匹配不到,cp就++,从下一个cp开始匹配
cp++;
}
//找不到
return NULL;
}
int main()
{
char arr1[] = "I am a student.";
char arr2[] = "a";
printf("%s\n", my_strstr(arr1, arr2));
return 0;
}
9. strtok—分割字符串
char * strtok ( char * str, const char * sep );
(1)sep参数是个字符串,定义了用作分隔符的字符集合
(2)第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
(3)strtok函数找到str中的下一个标记,并将其用\0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
(4)strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
(5)strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
(6)如果字符串中不存在更多的标记,则返NULL 指针。
使用:
int main()
{
char arr[] = "1206494879@qq.com";
const char *p = "@.";
//strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改
char buf[30] = { 0 };
strcpy(buf, arr);
//strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
char* ret = strtok(buf, p);
printf("%s\n", ret);
//strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
ret = strtok(NULL, p);
printf("%s\n", ret);
return 0;
}
10. strerror—返回错误码,所对应的错误信息
int main()
{
//打开文件
//打开文件的时候,如果文件的打开方式是"r"(只读)
//文件存在则打开成功,文件不存在打开失败
//打开文件失败的话,会返回NULL
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
printf("打开文件失败,原因是:%s\n", strerror(errno));
return 1;
}
}
二、字符函数
函数 如果他的参数符合下列条件就返回真
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 :任何可打印字符,包括图形字符和空白字符
三、内存操作函数
1. memcpy—内存拷贝
void * memcpy ( void * destination, const void * source, size_t num );
(1)函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
(2)这个函数在遇到 ‘\0’ 的时候并不会停下来。
(3)如果source和destination有任何的重叠,复制的结果都是未定义的。
使用:
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8 };
int arr2[] = { 3,4,5,6 };
//将arr2的前20个字节拷贝到arr1中
memcpy(arr1, arr2, 16);
int i = 0;
for (i = 0; i < 8; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
模拟实现:
void* my_memcpy(void* dest, const void* src, size_t num)
{
void* cp = dest;
while (num--)
{
//强转成char*类型,每次改变一个字节
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return cp;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7 };
int arr2[] = { 3,4,5 };
//将arr2的前12个字节拷贝到arr1中
my_memcpy(arr1, arr2, 12);
int i = 0;
for (i = 0; i < 7; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
2. memmove—重叠内存部分拷贝
(1)和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
(2)如果源空间和目标空间出现重叠,就得使用memmove函数处理。
使用:
int main()
{
int arr[] = { 1,2,3,4,5,6,7 };
memmove(arr + 2, arr, 12);
int i = 0;
for (i = 0; i < 7; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
模拟实现:
void* my_memmove(void* dest, void* src, size_t num)
{
void* cp = dest;
if (src > dest)
{
//从前往后
//强转成char*类型,每次改变一个字节
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
else
{
while (num--)
{
//从后往前
//强转成char*类型,每次加num个字节,找到src和dest末尾字节,从后往前一个字节一个字节改变
*((char*)dest + num) = *((char*)src + num);
}
}
return cp;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7 };
my_memmove(arr + 2, arr, 12);
int i = 0;
for (i = 0; i < 7; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
3. memcmp
比较从arr1和arr2指针开始的num个字节
int main()
{
char arr1[] = "abcde";
char arr2[] = "acde";
int ret = memcmp(arr1, arr2, 2);//比较前两个字节
printf("%d\n", ret); //-1 arr2大
return 0;
}
4. memset
int main()
{
char arr[] = "hello,world";
memset(arr, 'x', 5);
printf("%s\n", arr); //xxxxx,world
return 0;
}