字符函数和字符串函数
前言
C语言中对字符和字符串的处理很是频繁,但是C语言本身没有字符串类型的,字符串通常放在常量字符串中,或者字符串数组中,字符串常量适用于那些对它不做修改的字符串函数
一、求字符串长度
strlen(求字符串长度)
strlen函数介绍:
1.strlen函数,以‘\0’作为字符串的结束标志,strlen函数返回的是在字符串中‘\0’,之前出现的字符个数,不包含‘\0’。
strlen功能展示:
int main()
{
char arr[] = "abcdef";
int ret = strlen(arr);
printf("%d ", ret);
return 0;
}
strlen的模拟实现:my_strlen:
int my_strlen(char* arr)
{
int count = 0;
while (*arr)
{
count++;
arr++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
int ret = my_strlen(arr);
printf("%d", ret);
return 0;
}
二、长度不受限制的字符串函数
1.strcpy(字符串复制)
strcpy函数介绍:
destination:目的地
source:源头
1.源字符串必须有‘\0’为结束标志
2.也会将源字符串中的‘\0’拷贝到目标空间中
3.目标空间必须足够大,以确保能存放源字符串,而且目标空间必须可变。
strcpy功能展示:
int main()
{
char arr1[] = "abc";
char arr2[] = "xxxxxx";
printf("%s", strcpy(arr2, arr1));
return 0;
}
strcpy的模拟实现:my_strcpy
char* my_strcpy(char* det, const char* src)
{
char* ret = det;
assert(det);
assert(src);
while (*src)
{
*det++ = *src++;
}
return ret;
}
int main()
{
char arr1[20] = "hello world";
char arr2[] = "xxx";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
2.strcat(字符串拼接)
strcat函数介绍:
1.源字符串必须以’\0’结束
2.目标空间必须足够大,以确保能存放源字符串
3.目标空间必须可修改
函数功能展示:
int main()
{
char arr1[20] = "abc";
char arr2[] = "def";
printf("%s", strcat(arr1, arr2));
return 0;
}
strcat函数模拟实现:
char* my_strcat(char*dest, const char *src)
{
assert(dest && src);
char* ret = dest;
//1. 找目标空间中的\0
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;
}
3.strcmp
strcmp函数功能介绍:
- 如果第1个字符串大于第2个字符串,则返回大于0的数字。
- 如果第1个字符串等于第2个字符串,则返回0。
- 如果第1个字符串小于第2个字符串,则返回小于0的数字。
int main()
{
char arr1[] = "abc";
char arr2[] = "abf";
int ret = strcmp(arr1, arr2);
printf("%d ", ret);
return 0;
}
strcmp的模拟:my_strcmp
int main()
{
char arr1[] = "abc";
char arr2[] = "abf";
int ret = strcmp(arr1, arr2);
printf("%d ", ret);
return 0;
}
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
//VS
//> 1
//= 0
//< -1
//
int main()
{
int ret = my_strcmp("bbq", "bcq");
if (ret>0)
printf(">\n");
printf("%d\n", ret);
return 0;
}
三、长度受限制的字符串函数
1.strncpy
strncpy功能介绍:
- 拷贝num个字符从源字符串中到目标空间。
- 如果源字符串的长度小于num,则拷完源字符串之后在目标的后面追加0直到num个
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "xxx";
char* ret=strncpy(arr1, arr2,3);
printf("%s", ret);
return 0;
}
2.strncat
strncat函数功能的介绍:
从字符串追加字符
- 将源的第一个数字字符追加到目标,外加一个终止空字符。
- 将源的第一个数字字符追加到目标,外加一个终止空字符。如果源中 C 字符串的长度小于 num,则仅复制终止空字符之前的内容。
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "xxx";
char* ret=strncat(arr1, arr2,3);
printf("%s", ret);
return 0;
}
3.strncmp
strncmp函数功能介绍:
int main()
{
char arr1[20] = "abcdef";
char arr2[] = "abd";
int ret=strncmp(arr1, arr2,3);
printf("%d", ret);
return 0;
}
四、字符串查找
1.strstr
strstr函数功能介绍:
理解:这个字符串函数就是在一个字符串里面查找子字符串如果能够找到目标子字符串,就返回子字符串的首元素地址,依次往下读取,直到读取到‘\0’为止。
看下例代码:
int main()
{
char str[] = "This is a simple string";
char* pch;
pch = strstr(str, "simple");
printf("%s", pch);
return 0;
}
2.strtok
strtok函数功能介绍:
将字符串拆分为标记
例:
char* strtok (char* str,const char* sep)
- sep参数是个字符串,定义了用作分隔符的字符集合
- 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
- strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改
变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。) - strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
- strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
- 如果字符串中不存在更多的标记,则返回 NULL 指针。
例如:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "- This, a sample string.";
char* pch;
printf("Splitting string \"%s\" into tokens:\n", str);
pch = strtok(str, " ,.-");
while (pch != NULL)
{
printf("%s\n", pch);
pch = strtok(NULL, " ,.-");
}
return 0;
}
五、错误信息报告
strerror
strerror函数功能介绍:
/* strerror example : error list */
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pFile;
pFile = fopen("unexist.ent", "r");
if (pFile == NULL)
printf("Error opening file unexist.ent: %s\n", strerror(errno));
return 0;
}
六、内存操作函数
1.memcpy
memcpy函数功能介绍:
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 ‘\0’ 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的
/* memcpy example */
#include <stdio.h>
#include <string.h>
struct {
char name[40];
int age;
} person, person_copy;
int main ()
{
char myname[] = "Pierre de Fermat";
/* using memcpy to copy string: */
memcpy ( person.name, myname, strlen(myname)+1 );
person.age = 46;
/* using memcpy to copy structure: */
memcpy ( &person_copy, &person, sizeof(person) );
printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );
return 0;
}
2.memmove
memmove函数的功能介绍:
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
- 如果源空间和目标空间出现重叠,就得使用memmove函数处理。
/* memmove example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "memmove can be very useful......";
memmove (str+20,str+15,11);
puts (str);
return 0;
}
3.memcmp
memcmp的功能介绍:
/* memcmp example */
#include <stdio.h>
#include <string.h>
int main ()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
return 0;
}
七、内存操作函数的模拟实现:
1.memcpy的模拟:
void * memcpy ( void * dst, const void * src, size_t count)
{
void * ret = dst;
assert(dst);
assert(src);
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
2、memmove的模拟:
void * memmove ( void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count)) {
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else {
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}
好了,今天的分享就到这里了
如果对你有帮助,记得点赞👍+关注哦!
我的主页还有其他文章,欢迎学习指点。关注我,让我们一起学习,一起成长吧!
好了,今天的分享就到这里了