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

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

博客制作不易,欢迎各位点赞👍+收藏⭐+关注


目录

前言

一、字符串函数

1. strlen

2.strcpy

3. strcat

4. strcmp

5.strncpy

6. strncat
7. strncmp

8.strstr

9.strtok

二、错误信息报告

1.strerror

三、字符函数

四、内存操作函数

1. memcpy

2. memmove

3. memcmp

总结

前言

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

函数 作用
strlen 求字符串长度(不包含'\0')

strcpy

复制字符串
strcat 横向连接字符串
strcmp 比较两个字符串的大小,返回比较值
strncpy 根据提供的字节大小复制字符串大小
strncat 字符串末尾连接n个字符
strncmp 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完
strstr 搜索一个字符串在另一个字符串中的第一次出现。找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址; 如果未找到所搜索的字符串,则返回NULL
strtok 通过提供的分隔符字符串,将字符串分割成一个个片段
strerror 将错误码给转化成错误信息
memcpy 内存拷贝
memmove 拷贝一定长度的内存的内容
memset 在一段内存块中填充某个给定的值
memcmp

比较两个内存块

一、字符串函数

1. strlen

size_t strlen (const char* str);

注意:

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

2)参数的字符串必须要以'\0'结束,不能没有'\0';
3)注意函数的返回值是 size_t ,是无符号类型。

模拟实现函数:

#include<assert.h>
size_t my_strlen(const char* ch)
{
    assert(ch);
    size_t count = 0;
    while (*ch++)
    {
        count++;
    }
    return count;
}

2.strcpy

char* strcpy (char* destination, const char* source);

注意:

1)源字符串必须以 '\0' 结束;
2)该函数会将源字符串中的'\0'一同拷贝到目标空间,如果目标字符串原先就有内容,就会被拷贝的内容覆盖掉,包括'\0'也是;

3)目标空间必须足够大,以确保能存放源字符串,如果放不下就会造成数组越界访问,为非法访问空间;
4)目标空间必须可变,不能是常量字符串。

模拟实现函数:

#include<assert.h>
char* my_strcpy(char* dest, const char* src)
{
    char* p = dest;
    assert(src && dest);
    while(*dest++ = *src++)
        ;
    return p;
 }

3. strcat

char* strcat (char* destination, const char* source);

注意:

1)源字符串必须以 '\0' 结束;
2)目标空间必须有足够的大,能容纳下源字符串的内容;
3)目标空间必须可修改。

模拟实现函数:

#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

int strcmp ( const char * str1, const char * str2 );

注意:

1)第一个字符串大于第二个字符串,则返回大于0的数字;
2)第一个字符串等于第二个字符串,则返回0;
3)第一个字符串小于第二个字符串,则返回小于0的数字。
ps:在 VS 环境中,第一种情况返回的是 1 ,第二种情况同样返回 0 ,第三种情况返回 -1 。

模拟实现函数:

#include<assert.h>
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;
}

5.strncpy

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

注意:

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

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

6. strncat

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

注意:

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

7. strncmp

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

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

8.strstr

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

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

模拟实现函数:

#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 == '\0')
        return (char*)str1;
    while( *p1 )
    {
        while(*p1 == *p2 && *p1 != '\0')
        {
            p1++;
            p2++;
        }
        if(*p2 == '\0')
            return (char*)start1;
        start1++;
        p1 = start1;
        p2 = start2;
    }
    return NULL;
}

9.strtok

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

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

二、错误信息报告

1.strerror

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

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

注意:

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

#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

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

注意:

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

模拟实现函数:

#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

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

注意:

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

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

模拟实现函数:

#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网站找到它们,里面都有对每一个函数详细的各个部分的说明、作用的解析和示例,博主就不一一赘述了。

相关文章
|
7天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
23 6
|
27天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
34 10
|
20天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
26天前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
53 7
|
26天前
|
存储 编译器 程序员
【c语言】函数
本文介绍了C语言中函数的基本概念,包括库函数和自定义函数的定义、使用及示例。库函数如`printf`和`scanf`,通过包含相应的头文件即可使用。自定义函数需指定返回类型、函数名、形式参数等。文中还探讨了函数的调用、形参与实参的区别、return语句的用法、函数嵌套调用、链式访问以及static关键字对变量和函数的影响,强调了static如何改变变量的生命周期和作用域,以及函数的可见性。
29 4
|
1月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
23天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
19 0
|
23天前
|
C语言
【c语言】qsort函数及泛型冒泡排序的模拟实现
本文介绍了C语言中的`qsort`函数及其背后的回调函数概念。`qsort`函数用于对任意类型的数据进行排序,其核心在于通过函数指针调用用户自定义的比较函数。文章还详细讲解了如何实现一个泛型冒泡排序,包括比较函数、交换函数和排序函数的编写,并展示了完整的代码示例。最后,通过实际运行验证了排序的正确性,展示了泛型编程的优势。
19 0
|
27天前
|
算法 C语言
factorial函数c语言
C语言中实现阶乘函数提供了直接循环和递归两种思路,各有优劣。循环实现更适用于大规模数值,避免了栈溢出风险;而递归实现则在代码简洁度上占优,但需警惕深度递归带来的潜在问题。在实际开发中,根据具体需求与环境选择合适的实现方式至关重要。
25 0
|
C语言 图形学 数据格式
C语言库函数大全及应用实例一
[编程资料]C语言库函数大全及应用实例一 函数名: abort 功 能: 异常终止一个进程 用 法: void abort(void); 程序例: #i nclude #i nclude int main(void...
775 0