常用字符串函数拓展


我们在学习C语言时已经学习了一些常见的字符串函数,但这还不能满足我们的需求,为此我们拓展了几个常用的字符串函数。

字符串拓展函数

strncpy

函数原型为:

char * strncpy ( char * destination, const char * source, size_t num );

该函数用于从源字符串拷贝num个字符到目标空间,如果字符串的长度小于num,在拷贝完源字符串后,在目标后面追加0,直至num个字符。

strncat

函数原型为:

char * strncat ( char * destination, const char * source, size_t num );

该函数将源字符串前num个字符追加到目标空间中,追加完后自动在目标字符串后加上‘\0’,如果num大于源字符串的长度,最多也只会将源字符串全部追加到目标字符串后面。

strncmp

函数原型为:

int strncmp ( const char * str1, const char * str2, size_t num );

用于两个字符串的比较,比较到出现两个字符不一样或其中一个字符串结束或num个字符全部比完,
其返回值的含义为:
在这里插入图片描述

strstr

函数原型为:

const char * strstr ( const char * str1, const char * str2 );

该函数用于查找在str1中是否出现了str2,如果有,返回str2在str1中第一次出现的地址,否则返回空指针。

strtok

函数原型为:

char * strtok ( char * str, const char * delimiters );

· delimiters参数是个字符串,定义了用作分隔符的字符集合
· 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
· strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
· strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
· strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

· 如果字符串中不存在更多的标记,则返回 NULL 指针。

从加粗部分我们可以知道strtok函数具有记忆功能,因此我们若想将字符串分为多部分,第一次调用strtsr函数时str传非空指针,后面都要传空指针,直至分割完毕。

#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="This,a sample/string.";
  char * pch;
  pch = strtok (str,",/");//第一次传非空
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, ",/");//后面都传空指针
  }
  return 0;
}

输出结果为:
This
a simple
string.

strerror

函数原型为:

char * strerror ( int errnum );

该函数会返回错误码所对应的错误信息,可以通过printf函数将错误信息打印出来。
库函数在执行过程中发生了错误会将错误码放在errnum这个变量中,该变量是C语言提供的全局变量,记录最后一次错误信息的错误码,因此要包含头文件<errno.h>。

memcpy

函数原型为:

void * memcpy ( void * destination, const void * source, size_t num );

该函数是将souce开始的num个字节的内容拷贝到destination中,换言之,memcpy是对内存进行拷贝,而不只是单单拷贝字符串那么简单。这也意味着如果destination和source存在内存重叠,那么拷贝的内容是不确定的。

memmove

函数原型为:

void * memmove ( void * destination, const void * source, size_t num );

memmove函数是对memcpy函数的改进,解决了源内存块和目标内存块的内存不能重叠的问题。

memcmp

函数原型为;

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

用于比较ptr1和ptr2指针开始的num个字节
其返回值为:
在这里插入图片描述

memset

函数原型为:

void * memset ( void * ptr, int value, size_t num );

该函数用于将ptr开始的num个字节全部设为value,要注意是以一个字节为单位的。

库函数模拟实现

memmove

void * memmove ( void * destination, const void * source, size_t num );

要实现memmove函数,主要是解决内存重叠的问题。
我们的解决办法是:由拷贝字节大小和比较源空间与目标空间起始地址的大小来决定我们是选择从前往后还是从后往前拷贝内存。
在这里插入图片描述

void * memmove ( void * dst, const void * src, size_t count)
{
    void * ret = dst;
    if (dst <= src || (char *)dst >= ((char *)src + count)) 
     	{
          while (count--) 
	          {
	               *(char *)dst = *(char *)src;
	               dst = (char *)dst + 1;
	               src = (char *)src + 1;
	          }
    	}
   else 
    	{
          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);
}

qsort

可以对任意可以进行比较的数据进行排序
函数原型为:

qsort
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

相关参数介绍:
在这里插入图片描述

假如我们要对一个数组排升序,可以这样用:

#include <stdio.h>      /* printf */
#include <stdlib.h>     /* qsort */

int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int main ()
{
  int values[] = { 40, 10, 100, 90, 20, 25 };
  qsort (values, 6, sizeof(int), compare);
  return 0;
}

这里为了简便,选择冒泡排序进行模拟:

#include <stdio.h>
int int_cmp(const void * p1, const void * p2)
{
 	return (*( int *)p1 - *(int *) p2);
}

void _swap(void *p1, void * p2, int size)
{
	 int i = 0;
	 for (i = 0; i< size; i++)
	 {
		 char tmp = *((char *)p1 + i);
		 *(( char *)p1 + i) = *((char *) p2 + i);
		 *(( char *)p2 + i) = tmp;
	 }
 }
 void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{
	 int i = 0;
	 int j = 0;
	 for (i = 0; i< count - 1; i++)
	 {
		 for (j = 0; j<count-i-1; j++)
		 {
			 if (cmp ((char *) base + j*size , (char *)base + (j + 1)*size) > 0)
			 {
			 	_swap(( char *)base + j*size, (char *)base + (j + 1)*size, size);
			 }
		 }
	 }
}

由于其他函数的模拟比较容易实现,这里就不在一一进行模拟实现。至此,本文已经结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值