C语言/关于字符和字符串的库函数

2023-10-16 08:29:17 浏览数 (2)

 前言

在C语言中,由于字符串的操作较频繁,所以C语言本身提供了一些对于字符串处理的库函数。

函数

作用

strlen

求字符串长度(不包含'')

strcpy

复制字符串

strcat

横向连接字符串

strcmp

比较两个字符串的大小,返回比较值

strncpy

根据提供的字节大小复制字符串大小

strncat

字符串末尾连接n个字符

strncmp

比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完

strstr

搜索一个字符串在另一个字符串中的第一次出现。找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址; 如果未找到所搜索的字符串,则返回NULL

strtok

通过提供的分隔符字符串,将字符串分割成一个个片段

strerror

将错误码给转化成错误信息

memcpy

内存拷贝

memmove

拷贝一定长度的内存的内容

memset

在一段内存块中填充某个给定的值

memcmp

比较两个内存块

 一、字符串函数

1. strlen

代码语言:javascript复制
size_t strlen (const char* str);

注意:

1)字符串已经将 '' 作为结束标志,strlen函数返回的是在字符串中 '' 前面出现的字符个数(不包含 '' );

2)参数的字符串必须要以''结束,不能没有'';

3)注意函数的返回值是 size_t ,是无符号类型。

模拟实现函数:

代码语言:javascript复制
#include<assert.h>

size_t my_strlen(const char* ch)
{
    assert(ch);

    size_t count = 0;

    while (*ch  )
    {
        count  ;
    }

    return count;
}

2.strcpy

代码语言:javascript复制
char* strcpy (char* destination, const char* source);

注意: 

1)源字符串必须以 '' 结束; 2)该函数会将源字符串中的''一同拷贝到目标空间,如果目标字符串原先就有内容,就会被拷贝的内容覆盖掉,包括''也是; 3)目标空间必须足够大,以确保能存放源字符串,如果放不下就会造成数组越界访问,为非法访问空间; 4)目标空间必须可变,不能是常量字符串。

模拟实现函数:

代码语言:javascript复制
#include<assert.h>

char* my_strcpy(char* dest, const char* src)
{
    char* p = dest;

    assert(src && dest);

    while(*dest   = *src  )
        ;

    return p;
 }

3. strcat

代码语言:javascript复制
char* strcat (char* destination, const char* source);

注意: 

1)源字符串必须以 '' 结束; 2)目标空间必须有足够的大,能容纳下源字符串的内容; 3)目标空间必须可修改。 模拟实现函数:

代码语言:javascript复制
#include<assert.h>
#include<string.h>

char *my_strcat(char *str1, const char *str2)
{
    char *start = str1;

    assert(str1 && str2);
    str1  = strlen(str1);

    while( *str1   = *str2   )
        ;

    return start;
}

 4. strcmp

代码语言:javascript复制
int strcmp ( const char * str1, const char * str2 );

注意: 

1)第一个字符串大于第二个字符串,则返回大于0的数字; 2)第一个字符串等于第二个字符串,则返回0; 3)第一个字符串小于第二个字符串,则返回小于0的数字。

ps:在 VS 环境中,第一种情况返回的是 1 ,第二种情况同样返回 0 ,第三种情况返回 -1 。 模拟实现函数:

代码语言:javascript复制
#include<assert.h>

int my_strcmp(const char *str1, const char *str2)
{
    assert(str1 && str2);

    while(*str1 == *str2)
    {
        if(*str1 == '')
            return 0;

        str1  ;
        str2  ;
    }

    return *str1 - *str2;
}

5.strncpy

代码语言:javascript复制
char* strncpy (char* destination, const char* source, size_t num);

注意:

1)如果源字符串的长度小于 num ,则拷贝完源字符串之后,在目标的后边追加 '' ,直到 num 个;

2)拷贝 num 个字符就只会拷贝 num 个字符,不会再往后补上一个''。

6. strncat

代码语言:javascript复制
char* strcat (char* destination, const char* source, size_t num);

注意:

同样地,这个函数与 strcat 在使用上也只有新增一个参数来确认需要追加字符串中的多少个字符的区别而已,这个函数使用起来就比 strncpy 省心多了,因为这个函数会在追加之后再追加一个   ''。

7. strncmp

代码语言:javascript复制
char* strncmp (const char* str1, const char* str2, size_t num);

这个函数使用方法与 strcmp 相比也只有最后一个参数的区别,不多加说明。

8.strstr

代码语言:javascript复制
char* strstr (const char* str1, const char* str2);

这是一个可以判断一个字符串是否是另一个字符串的子串的函数。如果 str2 是 str1 的子串,即返回 str2 在 str1 中首次出现的位置的地址;如果不是则返回NULL。

模拟实现函数:

代码语言:javascript复制
#include<assert.h>

char* my_strstr(const char* str1, const char* str2)
{
    assert(str1 && str2);

    const char *p1 = str1;
    const char *p2 = str2;
    const char *start1 = p1;
    const char *start2 = p2;

    if(*str2 == '')
        return (char*)str1;

    while( *p1 )
    {
        while(*p1 == *p2 && *p1 != '')
        {
            p1  ;
            p2  ;
        }
        if(*p2 == '')
            return (char*)start1;
        
        start1  ;
        p1 = start1;
        p2 = start2;
    }

    return NULL;
}

9.strtok

代码语言:javascript复制
char* strtok (char* str, const char* sep);

 strtok,是一个可以按照给出的分隔符字符串,将字符串分割,我们进行第一次传参的时候,把字符串传过去,然后开始找分隔符,找到分隔符用''代替,当要进行第二次分割的的时候,传参传NULL即可,当传参传NULL的时候,strtok函数会找到上一次标记的地址,然后向后进行切割,如果在我们的字符串中,没有我们的分隔符,就会返回NULL。

二、错误信息报告

1.strerror

代码语言:javascript复制
char * strerror ( int errnum );

strerror是一个可以将错误码转换成错误信息的函数,其中我们的错误码会保存在一个叫做errno的函数中,它需要引头文件<errno.h>。

三、字符函数

函数

如果他的参数符合下列条件就返回真

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

任何可打印字符,包括图形字符和空白字符

大写 -> 小写

tolower

int tolower (int c);

小写 -> 大写

toupper

int toupper (int c);

四、内存操作函数

1. memcpy

代码语言:javascript复制
void* memcpy (void* destination, const void* source, size_t num);

注意:

1)函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置; 2)这个函数在遇到 '' 的时候并不会停下来; 3)如果source和destination有任何的重叠,复制的结果都是未定义的。

模拟实现函数:

代码语言:javascript复制
#include<assert.h>

void *my_memcpy(void *str1, const void *str2, size_t byte)
{
    assert(str1 && str2);
    
    size_t i = 0;
    while( i < byte )
    {
        *((char *)str1   i) = *((char *)str2   i);
        i  ;
    }

    return str1;
}

2. memmove

代码语言:javascript复制
void* memmove (void* destination, const void* source, size_t num);

注意:

1)和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的; 2)如果源空间和目标空间出现重叠,就得使用memmove函数处理。

模拟实现函数:

代码语言:javascript复制
#include<assert.h>

void *my_memmove(void *str1, const void *str2, size_t byte)
{
    assert(str1 && str2);
    
    size_t i = 0;
    if(str1 < str2)
    {
        while( i < byte )
        {
            *((char *)str1   i) = *((char *)str2   i);
            i  ;
        }
    }
    else
    {
        while( i < byte )
        {
            *((char *)str1   byte - i - 1) = *((char *)str2   byte - i - 1);
            i  ;
        }
    }

    return str1;
}

 3. memcmp

代码语言:javascript复制
int memcmp (const void* ptr1, const void* ptr2, size_t num);

注意:

1)比较从ptr1和ptr2指针开始的num个字节;

2)返回值由比较的两个字节内容大小决定。

模拟实现函数:

代码语言:javascript复制
#include<assert.h>

int my_memcmp(const void *str1, const void *str2, size_t byte)
{
    assert(str1 && str2);

    size_t i = 0;

    for(i = 0; i < byte; i  )
    {
        if( *((char *)str1   i) != *((char *)str2   i) )
            return *((char *)str1   i) - *((char *)str2   i);
    }

    return 0;
}

总结

上述函数都是我们常会在代码中使用到的,熟练掌握起来为我们提供很大的帮助。当然,除此之外,C语言的库函数中还有许多有趣的有关字符和字符串的函数,如果你有兴趣想要了解,可以通过cplusplus网站或cppreference网站找到它们,里面都有对每一个函数详细的各个部分的说明、作用的解析和示例,博主就不一一赘述了。

0 人点赞