C语言的string库中常用函数功能描述及实现,这篇文章介绍的主要是string提供的内存操作的函数。

strcpy

函数原型: char *strcpy( char *dest, const char *src );

功能: 将src 指向的字符串(包括终止字符)拷贝到dest 指向的地址,返回值是dest 的地址

实现:

char *strcpy( char *dest, const char *src) {
	char *ret = dest;
    while (true) {
        *ret++ = *src;
        if (*src++ == '\0'){
            *ret++ = '\0';
            return ret;
        }    
    }
}

注意,以下情况会出现未定义:

  • dest的容量不足以存放src的字符串
  • dest 和 src 的内存重叠
  • dest不是指向一个字符串(字符数组的指针)或src不是以终止符结束

char *strncpy( char *dest, const char *src, size_t count ); 拷贝指定数量的字符。

strcat

函数原型: char *strcat( char *dest, const char *src );

功能: 将src 指向的字符串(包括终止字符)拼接到dest 指向的字符的末尾,返回值是dest 的地址

实现:

char *strcat( char *dest, const char *src) {
	char *ptr = dest;
    while (*ptr++);
    while (true) {
        *ptr++ = *src++;
        if (*src == '\0') {
            *ptr++ = '\0';
            return dest;
        }
    }
}

注意,以下情况会出现未定义:

  • dest的容量不足以存放src的字符串
  • dest 和 src 的内存重叠
  • dest不是指向一个字符串(字符数组的指针)或src不是以终止符结束

char *strncat( char *dest, const char *src, size_t count ); 拼接指定个数的字符

strlen

函数原型: size_t strlen( const char *str );

功能: 计算src 指向的字符串的长度,不包括末尾的结束符

实现:

size_t strlen( const char *str ) {
	    size_t len = 0;
    while (str[len]) {
        len++;
    }
    return len;
}

// 第二种实现
size_t strnlen(const char *str)
{
    char *ptr = (char *)str;
    while (*ptr != '\0'){
        ptr++;
    }
    return ptr - str;
}

注意,以下情况会出现未定义:

  • str 指向的不是一个以终止符结束的字符串

size_t strnlen_s( const char *str, size_t strsz ); 指定可以计算的最大长度

strcmp

函数原型: int strcmp( const char *lhs, const char *rhs );

功能: 以字典序判断 lhs rhs 指向的字符串大小;返回负值, lhs < rhs, 返回0 , lsh = rhs, 返回正值 lhs > rhs

实现:

int strcmp(const char *lhs, const char *rhs){
    while (*lhs == *rhs && *lhs != '\0' && *rhs != '\0'){
        lhs++;
        rhs++;
    }
    return *lhs < *rhs ? -1 : *lhs > *rhs;
}

int strncmp( const char* lhs, const char* rhs, size_t count ); 比较指定个数的字符

strchr

函数原型: char *strchr( const char *str, int ch );

功能:查找chstr 指向的字符串中第一次出现的位置,如果存在返回查找到的地址,否则返回空指针;

实现:

char *strchr( const char *str, int ch ){
    char* ptr = (char *) str;
    while (*ptr != '\0') {
        if (*ptr == ch) {
            break;
        }
        *ptr++;
    }
    return ptr;
}

char *strrchr( const char *str, int ch ); 查找指定字符最后一次出现的位置

memcmp

函数原型: int memcmp( const void* lhs, const void* rhs, size_t count );

功能:从 lhsrhs 指向的第一个内存位置到 count 位置的数据是否相同(按字典序比较)。 返回负值, lhs > rhs;返回0,lhs = rhs; 返回正值, lhs < rhs.

实现:

int memcmp( const void* lhs, const void* rhs, size_t count ){
    char *lptr = (char *)lhs;
    char *rptr = (char *)rhs;
    while ((count > 0) && *lptr == *rptr)
    {
        lptr++;
        rptr++;
        count--;
    }
    if (count == 0)
        return 0;
    return *lptr < *rptr ? -1 : *lptr > *rptr;
}

memset

函数原型: void *memset( void *dest, int ch, size_t count );

功能:将 countch 字符拷贝到 dest 指向的地址, 返回dest的地址。

实现:

int memcmp( const void* lhs, const void* rhs, size_t count ){
    char *lptr = (char *)lhs;
    char *rptr = (char *)rhs;
    while ((count > 0) && *lptr == *rptr)
    {
        lptr++;
        rptr++;
        count--;
    }
    if (count == 0)
        return 0;
    return *lptr < *rptr ? -1 : *lptr > *rptr;
}

memcpy

函数原型: void* memcpy( void *dest, const void *src, size_t count );

功能:类似于 strcpy, 从src 中将 count 个字节的数据拷贝到 dest 中,返回 dest的地址

实现:

void* memcpy( void *dest, const void *src, size_t count );{
    char *ptr = dest;
    while (count--)
    {
        *ptr++ = *((char *)(src++));
    }
    return dest;
}

memchr

函数原型: void *memchr(const void *str, int ch, size_t count);

功能:类似于 strchr, 从str 的前count 个字节中查找ch 第一次出现的位置,返回第一次出现的地址

实现:

void *memchr(const void *str, int ch, size_t count) {
    char *ptr = (char *)str;
    while (count--)
    {
        if (*ptr == ch)
        {
            return (void *)ptr;
        }
        ptr++;
    }
}

memmove

函数原型: void* memmove( void* dest, const void* src, size_t count );

功能:功能于 memcpy 一样,但是比memcpy 更加安全,可以处理destsrc 出现内存重叠的问题。src < dest , 从后向前逐个字节复制;src > dest 从前向后逐个字节复制。

实现:

void* memmove(void* dest, const void* src, size_t count )
{
    char* dest_ptr = (char*)dest;
    const char* src_ptr = (const char*)src;
    if (dest_ptr < src_ptr) {
        for (size_t i = 0; i < num; i++) {
            *(dest_ptr + i) = *(src_ptr + i);
        }
    } else {
        for (size_t i = num; i != 0; i--) {
            *(dest_ptr + i - 1) = *(src_ptr + i - 1);
        }
    }
    return dest;
}

参考