在C语言中函数的学习也是一个很重要的知识板块,下文将为读者介绍一下如何运用一些字符串函数和内存函数
字符串函数
1 求字符串长度的函数:strlen
2 复制字符串的函数: strcpy , strncpy
3 追加字符串的函数: strcat , strncat
4 比较字符串的函数: strcmp , strncmp
5 查找子串的函数: strstr
6 截断字符串的函数: strtok
7 报告错误信息的函数: strerror
内存函数
1 不同内存块之间的复制函数:memcpy
2 内存块出现重叠的复制函数:memmove
3 给内存块的赋值函数: memset
4 内存块之间的比较函数:memcmp
求字符串长度的函数:strlen
该函数原型可以从msdn中查找到:size_t strlen( const char *string ),所对应的头文件是string.h
size_t代表了返回一个无符号整形,传入的是要查询长度的字符串的首地址,要注意到,字符串是以‘ \0 ’结尾的,所以这个函数的原理就是从起始地址开始检查,一旦遇到‘\0’结束,并记录‘\0’之前的字符个数。
最后返回一个无符号整形,即字符个数。
所以我们可以根据这样来复现这个函数
第一种是计数器的方式来实现
第二种是不创建临时变量,采用递归的方式来实现
第三种是用指针减去指针的方式去实现
复制字符串的函数: strcpy , strncpy
这两个函数第一个是复制的长度无限制,第二个是复制的长度有限制,在MSDN中的函数原型分别是
strcpy: char *strcpy( char *strDestination, const char *strSource );
strncpy: char *strncpy( char *strDest, const char *strSource, size_t count );
我们可以看到第二个函数只是多了一个要复制字符串长度的量
而对于这两个函数的模拟实现,第一个就是一直复制到’\0’,而第二个就根据给定的长度来复制
这两个函数最后都是返回目标字符串的地址
strcpy:
strncpy:
追加字符串的函数: strcat , strncat
同上两个函数一样,只是后一个多了长度的限制
在MSDN中两函数原型是
strcat: char *strcat( char *strDestination, const char *strSource );
strncat:char *strncat( char *strDest, const char *strSource, size_t count );
最后会返回目标字符串的地址
strcat:
strncat:
比较字符串的函数: strcmp , strncmp
二者函数在MSDN中的函数原型分别是
strcmp: int strcmp( const char *string1, const char *string2 );
strncmp: int strncmp( const char string1, const char string2, size_t count );
strcmp是一个比较有趣的函数,因为它的机理是逐个比较字符的大小,如果string1小于string2,那么它将返回一个小于0的数字,如果大于那么返回一个大于0的数字,如果这两个字符相等,则继续往下比,如果比到最后也相同则返回0。其实也就是只要遇到不同的字符,这个函数也就结束了。
strcmp:
strncmp:
查找子串的函数: strstr
strstr在MSDN中的函数原型:char *strstr( const char *string, const char *strCharSet );
这个函数有三种返回值,如果strCharSet 不在string中,返回空指针
如果strCharSet 为空指针,返回string的地址
如果strCharSet 在string中,返回strCharSet 在string中对应的地址
如下图
strstr:
下面附上代码
char*my_strstr(const char *string, const char *strcheck)
{
assert(*string);
const char * p1 = string;
if (*strcheck == '\0')
{
return (char*)string;
}
while (*p1)
{
const char * p2 = strcheck;
const char *p3 = p1;
while (*p3 !='\0'&& *p3 == *p2 && *p2 !='\0')
{
p3++;
p2++;
}
if (*p2 == '\0')
{
return (char *)p1;
}
p1++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdefghijk";
char arr2[] = "bcd";
if (my_strstr(arr1, arr2) == NULL)
{
printf("No\n");
}
else if (my_strstr(arr1, arr2) == arr1)
{
printf("arr2 is empty arrary\n");
}
else
{
printf("%p\n", my_strstr(arr1, arr2));
printf("%p\n", arr1);
printf("%p\n", arr2);
}
}
** 截断字符串的函数: strtok**
该函数在MSDN中的函数原型是:char *strtok( char *strToken, const char *strDelimit )
第一个地址是要剪切的字符串的地址,第二个字符串是用作分隔符的字符的集合
第一个参数指定的字符串,它包含了0个或者多个由strDelimit 字符串中一个或者多个分隔符分割的标记。
strtok函数找到strToken中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。
(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针。下面有两个例子
报告错误信息的函数: strerror
strerror在MSDN中的函数原型是:char *strerror( int errnum );
errnum是错误代码对应的数字,根据不同的数字,返回不同错误解释的地址
下面给出一个例子
不同内存块之间的复制函数:memcpy
memcpy在MSDN中的函数原型是:void *memcpy( void *dest, const void *src, size_t count );
第一个是目标地址,第二个是源地址,第三个是复制的字节数
最后则会返回目标地址
要注意C语言中只规定memcpy的作用是在不同内存块之中起作用就可以,有些编译器在有重叠的内存块中也能实现
所以下图中模拟实现中,是在arr1和arr2之间进行拷贝
memcpy:
内存块出现重叠的复制函数:memmove
memmove在MSDN中的原函数是:void *memmove( void *dest, const void *src, size_t count );
参数意义和memcpy差不多,只是memmove是在内存块可以重叠的区域中也满足
下面附上代码
void print(int *arr, size_t i)
{
size_t j = 0;
for (; j < i; j++)
{
printf("%d ",arr[j]);
}
}
void * my_memmove(void *dest, const void * src, size_t count)
{
void *p1 = dest;
if (src < dest)//源地址小于目标地址需要从后到前进行拷贝,否则会出现重复覆盖的情况,致使拷贝失败
{
while (count--)
{
*((char *)dest + count) = *((char *)src + count);
}
return p1;
}
else //否则就从前到后进行拷贝
{
while (count--)
{
*(char *)dest = *(char *)src;
((char *)dest)++;
((char *)src)++;
}
return p1;
}
}
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
my_memmove(arr + 3, arr, 20);
print(arr,10);
}
给内存块的赋值函数: memset
memset在MSDN中的函数原型是:void *memset( void *dest, int c, size_t count );
第一个参数是目标内存的地址,第二个是要设置的字符对应的ASCII码值,第三个是要设置的个数
最后返回目标内存地址
下面举个栗子(第二张是一张不全的ASCII码表)
内存块之间的比较函数:memcmp
memcmp在MSDN中的函数原型是:int memcmp( const void *buf1, const void *buf2, size_t count );
第一个和第二个参数分别是两个内存地址,然后从两个地址开始比较count个字节。
原理和strcmp差不多
下面举个栗子,由于G的ASCII码值是小于g的ASCII码值,所以当比较到第三个字节的时候,就出现结果了
看到这,希望这篇文章对你有所帮助,感谢观看!一起加油吧!