C语言之<string.h>头文件函数详解

公众号:嵌入式不难

本文仅供参考学习,如有错误之处,欢迎留言指正。




void *memcpy(void *dest, const void *src, size_t n);
描述:从src内存空间中复制n字节至dest内存空间,不允许src内存空间和dest内存空间重叠。
返回值:dest指针

void *memmove(void *dest, const void *src, size_t n);
描述:从src内存空间中复制n字节至dest内存空间,允许src内存空间和dest内存空间重叠,实现方案为先将src内存空间拷贝至临时缓存,再将临时缓存的内容拷贝至dest内存空间。
返回值:dest指针

void *memccpy(void *dest, const void *src, int c, size_t n);
描述:最多从src内存空间中复制n字节至dest内存空间,复制过程中如在src内存空间中遇到字符c则停止复制,但字符c会被复制至dest内存空间。如果内存空间重叠,则函数运行结果未知。
返回值:
非NULL:dest内存空间存储字符c的下一个字符地址;
NULL:src内存空间中的前n字节没有字符c,且完整拷贝n字节。

void *memset(void *s, int c, size_t n);
描述:设置s内存空间的前n字节的值为c
返回值:s指针

int memcmp(const void *s1, const void *s2, size_t n);
描述:对比s1内存空间和s2内存空间的前n字节
返回值:
等于0:当n为0时,始终返回0;
小于0:s1s2内存值不同,且不同的地址s1-s2<0;
等于0:s1s2n字节值的值完全相同;
大于0:s1s2内存值不同,且不同的地址s1-s2>0;

void *memchr(const void *s, int c, size_t n);
描述:在s内存空间的前n字节查找ccs内存空间的值被认定为unsigned char
返回值:
非NULL:sn字节中匹配c的地址
NULL:sn字节中没有出现c

void *memrchr(const void *s, int c, size_t n);
描述:在s内存空间的前n字节查找ccs内存空间的值被认定为unsigned char,其功能和memchr一样,只是memchr顺序向前查找(s[0], s[1]…s[n-1]),而从memchr倒序向后查找(s[n-1], s[n-2]…s[0])
返回值:
非NULL:sn字节中匹配c的地址
NULL:sn字节中没有出现c

void *rawmemchr(const void *s, int c);
描述:在s开始地址空间查找c,其功能和memchr一样,但是rawmemchr可以快速的检索出值c的地址(不使用计数来限定检索范围),前提是调用者已经确定值c一定会出现在s中,否则结果将不可预测。
返回值:返回s空间中首次匹配值c的地址,如果不匹配,结果将不可预测。

void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
描述:查找haystack的前haystacklen内存中中首次出现地址为needle长度为needlelen的内存值
返回值:
非NULL:haystack中首次出现needle内存的地址
NULL:haystack中没有出现needle内存

char *strcpy(char *dest, const char *src);
描述:将src字符串拷贝至dest缓存地址中,包括拷贝终止符'\0'。字符串地址不允许重叠,且dest缓存空间应足够长至接收src字符串。
返回值:dest指针

char *strncpy(char *dest, const char *src, size_t n);
描述:最多将src字符串的前n字节拷贝至dest缓存地址中
src长度>=n时,只拷贝n字节至dest
src长度<n时,先拷贝srcdest,然后将剩余空间置为终止符'\0'
返回值:dest指针

char *strcat(char *dest, const char *src);
描述:将src字符串追加至dest字符串末尾,从dest首次出现终止符'\0'的位置开始追加,并覆盖终止符'\0',追加完成后向dest添加新的终止符'\0'
返回值:dest指针

char *strncat(char *dest, const char *src, size_t n);
描述:最多将src字符串的前n字节追加至dest字符串末尾
src长度>=n时,先将src的前n字节追加至dest,并再追加一个终止符'\0'
src长度<n时,先将src完整追加至dest,并再追加一个终止符'\0'
返回值:dest指针

int strcmp(const char *s1, const char *s2);
描述:对比s1字符串和s2字符串
返回值:
小于0:s1s2字符串不同,且不同的地址s1-s2<0;
等于0:s1s2字完全相同;
大于0:s1s2字符串不同,且不同的地址s1-s2>0;

int strncmp(const char *s1, const char *s2, size_t n);
描述:对比s1字符串和s2字符串的前n字节
返回值:
小于0:s1s2字符串不同,且不同的地址s1-s2<0;
等于0:s1s2字完全相同;
大于0:s1s2字符串不同,且不同的地址s1-s2>0;

int strcoll(const char *s1, const char *s2);
描述:按照LC_COLLATE确定字符串的比较和排序方式对比s1字符串和s2字符串
返回值:
小于0:s1s2字符串不同,且不同的地址s1-s2<0;
等于0:s1s2字完全相同;
大于0:s1s2字符串不同,且不同的地址s1-s2>0;

size_t strxfrm(char *dest, const char *src, size_t n);
描述:将src字符串的前n字节按照LC_COLLATE确定字符串的排序方式转换存储至dest缓存地址中
返回值:需要存储在dest的字节数(不包括终止符'\0')。如果返回值大于等于n,则dest的内容是不确定的。

char *strdup(const char *s);
描述:使用malloc新建一个与s一模一样的字符串,并返回malloc分配出的地址,不需要使用新建的字符串时,需要用free释放相应的内存空间
返回值:
非NULL:malloc新建的s字符串副本的地址
NULL:malloc新建副本失败

char *strndup(const char *s, size_t n);
描述:使用malloc新建字符串s的副本,最多只取s字符串的前n字节,并返回malloc分配出的地址,不需要使用新建的字符串时,需要用free释放相应的内存空间
返回值:
非NULL:malloc新建的字符串副本地址
NULL:malloc新建字符串副本失败

char *strdupa(const char *s);
描述:使用alloca在栈上新建一个与s一模一样的字符串,并返回alloca分配出的地址,系统根据栈规则回收内存。
返回值:
非NULL:alloca新建字符串副本的地址
NULL:alloca新建字符串副本失败

char *strndupa(const char *s, size_t n);
描述:使用alloca在栈上新建字符串s的副本,最多只取s字符串的前n字节,并返回alloca分配出的地址,系统根据栈规则回收内存。
返回值:
非NULL:alloca新建的字符串副本地址
NULL:alloca新建字符串副本失败

char *strchr(const char *s, int c);
描述:在s字符串中查找首次出现字符c的地址,s字符串的检索范围包含终止符'\0',且字符c可以为终止符'\0'
返回值:
非NULL:s中首次匹配c的地址
NULL:s中没有出现c

char *strrchr(const char *s, int c);
描述:在s字符串中查找最后一次出现字符c的地址,s字符串的检索范围包含终止符'\0',且字符c可以为终止符'\0'
返回值:
非NULL:s中最后一次匹配c的地址
NULL:s中没有出现c

char *strchrnul(const char *s, int c);
描述:在s字符串中查找首次出现字符c的地址,s字符串的检索范围包含终止符'\0',且字符c可以为终止符'\0'
返回值:当查找到字符c时返回cs中的地址;否则返回s中终止符'\0'的地址

size_t strspn(const char *s, const char *accept);
描述:统计s字符串开始地址有多少个字符(不包含终止符'\0')连续属于accept字符串集,s字符值等于accept中的字符时计数增1,s地址自增1,不等时退出计数(函数返回)。
返回值:s中有多少个字符连续属于accept字符串
举例:

#include <string.h>
#include <stdio.h>
int main(void)
{
    char *s = "test tt bb pp jj-j";
    char *accept = "j test pb";
    size_t len = strspn(s, accept);

    printf("s 中有 %ld 个字符连续属于 accept\n", len);
    return 0;
}
// s 中有 16 个字符连续属于 accept

size_t strcspn(const char *s, const char *reject);
描述:统计s字符串开始地址有多少个字符(不包含终止符'\0')连续不属于reject字符串集,s字符值不等于reject中的字符时计数增1,s地址自增1,相等时退出计数(函数返回)。
返回值:s中有多少个字符连续不属于accept字符串
举例:

#include <string.h>
#include <stdio.h>
int main(void)
{
    char *s = "test tt bb pp jj-j";
    char *accept = "j pb";
    size_t len = strcspn(s, accept);

    printf("s 中有 %ld 个字符连续不属于 accept\n", len);
    return 0;
}
// s 中有 4 个字符连续不属于 accept

char *strpbrk(const char *s, const char *accept);
描述:定位首次出现在s字符串中属于accept字符串中任一字符(不包含终止符'\0')的地址。
返回值:
非NULL:s中首次匹配accept任一字符的地址
NULL:s中没有出现accept中的任一字符
举例:

#include <string.h>
#include <stdio.h>
int main(void)
{
    char *s = "1234567";
    char *accept = "43";
    char * ret = strpbrk(s, accept);

    printf("s 中首次出现 accept 的字符为(%c), ret=%s\n", *ret, ret);
    return 0;
}
// s 中首次出现 accept 的字符为(3), ret=34567

char *strstr(const char *haystack, const char *needle);
描述:查找haystack字符串中首次出现needle字符串的地址,比较不包含终止符'\0'
返回值:
非NULL:haystack中首次出现needle字符串的地址
NULL:haystack中没有出现needle字符串

char *strcasestr(const char *haystack, const char *needle);
描述:查找haystack字符串中首次出现needle字符串的地址,比较忽略haystackneedle中的大小写,且不包含终止符'\0'
返回值:
非NULL:haystack中首次出现needle字符串的地址(忽略大小写)
NULL:haystack中没有出现needle字符串

char *strtok(char *str, const char *delim);
描述:将str字符串分割成许多子字符串,分隔符为delim字符串中的每一个字符,delim中任一字符在str中首次出现,且产生有效字符串(字符串长度不为0)时,函数返回子字符串,产生子字符串时,str中命中的分隔符将被置为终止符'\0'
返回值:
非NULL:strdelim的子字符串地址
NULL:str已无法被delim分割
注意事项:
1. 在第一次调用strtok时应制定str参数,而在后续对同一strstrtok调用时str参数必须NULL,在后续调用中delim可以指定不同的字符串
2.str如果开头就出现了分隔符,则开头的分隔符不会被置为终止符'\0'
举例:

#include <string.h>
#include <stdio.h>
 
int main () {
    char str[] = ":---;This is:-;strtok-test:;";
    size_t len = strlen(str);
    const char delim[] = "-;:";

    printf("start str=%s\n", str);
    char *token = strtok(str, delim);
    while( token != NULL ) {
        printf( "token=%s\n", token );
        token = strtok(NULL, delim);
    }
    printf("end str=%s\n", str);
    printf("char str=");
    for(int i=0;i<len;i++){
        if(str[i]) printf("%c", str[i]);
        else printf("/");
    }
    printf("\n");
    return(0);
}
/*
start str=:---;This is:-;strtok-test:;
token=This is
token=strtok
token=test
end str=:---;This is
char str=:---;This is/-;strtok/test/;
*/

char *strtok_r(char *str, const char *delim, char **saveptr);
描述:将str字符串分割成许多子字符串,分隔符为delim字符串中的每一个字符,delim中任一字符在str中首次出现,且产生有效字符串(字符串长度不为0)时,函数返回子字符串,产生子字符串时,str中命中的分隔符将被置为终止符'\0'strtok_r函数为strtok函数的可重入版本和线程安全版,saveptr用于保存被分割后产生的子字符串终止符'\0'的下一个地址,用于维护解析相同字符串的连续调用之间的上下文。
返回值:
非NULL:strdelim的子字符串地址
NULL:str已无法被delim分割
注意事项:
1. 在第一次调用strtok时应制定str参数,而在后续对同一strstrtok调用时str参数必须NULL,在后续调用中delim可以指定不同的字符串
2.str如果开头就出现了分隔符,则开头的分隔符不会被置为终止符'\0'
3. 用户禁止修改saveptr的值,用户可以忽略saveptr
举例:

#include <string.h>
#include <stdio.h>
 
int main () {
    char str[] = ":---;This is:-;strtok-test:;";
    size_t len = strlen(str);
    const char delim[] = "-;:";
    char *saveptr;

    printf("start str=%s\n\n", str);
    char *token = strtok_r(str, delim, &saveptr);
    while( token != NULL ) {
        printf( "token=%s\n", token );
        printf( "saveptr=%s\n\n", saveptr );
        token = strtok_r(NULL, delim, &saveptr);
    }
    printf("end str=%s\n", str);
    printf("char str=");
    for(int i=0;i<len;i++){
        if(str[i]) printf("%c", str[i]);
        else printf("/");
    }
    printf("\n");
    return(0);
}
/*
start str=:---;This is:-;strtok-test:;

token=This is
saveptr=-;strtok-test:;

token=strtok
saveptr=test:;

token=test
saveptr=;

end str=:---;This is
char str=:---;This is/-;strtok/test/;
*/

size_t strlen(const char *s);
描述:计算s字符串的长度,不包括终止符'\0'
返回值:s字符串的长度

size_t strnlen(const char *s, size_t maxlen);
描述:计算s字符串的长度,计算地址最多至s+maxlen(不包括s[maxlen]),不包括终止符'\0'
返回值:s字符串的长度

char *strerror(int errnum);
描述:返回errnum错误码的描述(字符串格式),返回的字符串地址为全局变量,后续的strerrorstrerror_l调用均会修改地址指向的内存。
返回值:错误码的字符串描述(符合LC_MESSAGES) / "Unknown error nnn"

int strerror_r(int errnum, char *buf, size_t buflen);/* XSI-compliant */
描述:将errnum错误码的描述(字符串格式)保存至buf地址中,buflen指明buf地址的最大接收长度,当buflen大于0时,strerror_r始终会保存一个终止符'\0'buf中,strerror_r始终为buf设置一个终止符'\0'
返回值:
0:保存至buf成功,buflen足以接收错误码描述
大于0:发生错误,返回错误码,buflen不足以完整的接收错误码描述,尽多接收错误码描述
-1:发生错误,错误码保存在errno

char *strerror_r(int errnum, char *buf, size_t buflen);/* GNU-specific */
暂时没有分析

char *strerror_l(int errnum, locale_t locale);
描述:返回errnum错误码的字符串描述,错误码字符串为与语言环境locale相关的错误消息,返回的字符串地址为全局变量,后续的strerrorstrerror_l调用均会修改地址指向的内存。
返回值:错误码的字符串描述

void bzero(void *s, size_t n);
描述:将s内存空间开始的n置为0
返回值:无

void bcopy(const void *src, void *dest, size_t n);
描述:从src内存空间中复制n字节至dest内存空间,允许src内存空间和dest内存空间重叠,注意和memcpy的参数顺序是相反的。
返回值:无

int bcmp(const void *s1, const void *s2, size_t n);
描述:对比s1内存空间和s2内存空间的前n字节,同memcmp
返回值:
等于0:当n为0时,始终返回0;
小于0:s1s2内存值不同,且不同的地址s1-s2<0;
等于0:s1s2n字节值的值完全相同;
大于0:s1s2内存值不同,且不同的地址s1-s2>0;

char *index(const char *s, int c);
描述:在s字符串中查找首次出现字符c的地址,s字符串的检索范围包含终止符'\0',且字符c可以为终止符'\0',同strchr
返回值:
非NULL:s中首次匹配c的地址
NULL:s中没有出现c

char *rindex(const char *s, int c);
描述:在s字符串中查找最后一次出现字符c的地址,s字符串的检索范围包含终止符'\0',且字符c可以为终止符'\0',同strrchr
返回值:
非NULL:s中最后一次匹配c的地址
NULL:s中没有出现c

int ffs(int i);int ffsl(long int i);int ffsll(long long int i);
描述:返回i的最低有效位bit0的值
返回值:i最低有效位bit0的值

int strcasecmp(const char *s1, const char *s2);
描述:对比s1字符串和s2字符串,与strcmp不同的是strcasecmp忽略大小写
返回值:
小于0:s1s2字符串不同,且不同的地址s1-s2<0;
等于0:s1s2字完全相同;
大于0:s1s2字符串不同,且不同的地址s1-s2>0;

int strncasecmp(const char *s1, const char *s2, size_t n);
描述:对比s1字符串和s2字符串的前n字节,与strncmp不同的是strncasecmp忽略大小写
返回值:
小于0:s1s2字符串不同,且不同的地址s1-s2<0;
等于0:s1s2字完全相同;
大于0:s1s2字符串不同,且不同的地址s1-s2>0;

char *strsep(char **stringp, const char *delim);
描述:将*stringp字符串分割成许多子字符串,分隔符为delim字符串中的每一个字符,delim中任一字符在*stringp中首次出现时,函数立即返回子字符串(即使字符串内没有有效字符,仅有一个终止符'\0'),产生子字符串时,*stringp中命中的分隔符将被置为终止符'\0',且stringp的值被更新至终止符'\0'的下一个地址。
返回值:
非NULL:*stringpdelim的子字符串地址,有可能该子字符串仅有一个终止符'\0'
NULL:*stringp已无法被delim分割,或*stringpNULL
注意事项:
1. 用户禁止修改*stringp的值,用户可以忽略*stringp
2. 子字符串可能仅有一个终止符'\0'
举例:

#include <string.h>
#include <stdio.h>
 
int main () {
    char str[] = ":---;This is:-;strsep-test:;";
    size_t len = strlen(str);
    const char delim[] = "-;:";
    char *stringp = str;

    printf("start str=%s\n", str);
    char *token = strsep(&stringp, delim);
    while( token != NULL ) {
        printf( "token=%s\n", token );
        token = strsep(&stringp, delim);
    }
    printf("end str=%s\n", str);
    printf("char str=");
    for(int i=0;i<len;i++){
        if(str[i]) printf("%c", str[i]);
        else printf("/");
    }
    printf("\n");
    return(0);
}
/*
start str=:---;This is:-;strsep-test:;
token=
token=
token=
token=
token=
token=This is
token=
token=
token=strsep
token=test
token=
token=
end str=
char str=/This is///strsep/test//
*/

char *strsignal(int sig);
描述:返回sig信号的描述(字符串格式),返回的字符串地址仅供函数内的下文调用
返回值:sig的信号描述

int strverscmp(const char *s1, const char *s2);
暂时没有分析

char *strfry(char *string);
描述:使用rand来随机打乱string字符串中的字符排序,并返回新的字符串
返回值:string字符串的乱序字符串
疑问:乱序字符串的内存来自于哪里?


版权声明:本文为qq_39257301原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。