C语言字符串处理函数

原链接:点击打开链接

偏底层的工程项目中,我们经常会遇到要用C语言来直接处理字符串,了解这些函数,编写起代码来能够事半功倍,这也是字符串处理的基础。C语言直接操作内存,所以需要完全理解这些函数在做什么,并且时刻注意安全检查,才能尽量避免一些奇怪的错误(这也是使用C语言的缺点)。一般地,使用这些函数,需要包含头文件:

#include <string.h>

1. strcpy

原型:char *strcpy (char * __dest, const char * __src); 
功能:将一个字符串(__src)拷贝到另一个字符串缓冲区中(__dest),并返回拷贝后的字符串指针; 
例子:

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

int main(){
    const char* str1 = "abcdefg";
    char str2[32];
    strcpy(str2,str1);
    printf("after copy, str2 = %s\n",str2);
    return 0;
}

运行结果:

after copy, str2 = abcdefg

注意: 
1. 必须保证拷贝后的缓冲区即上例中str2的大小足够,否则造成内存溢出到未分配的地址,容易产生各种未知错误; 
2. 由于该函数原理是逐字节复制,所以如果str1和str2的空间有重叠,则会造成覆盖,可以看下面这个例子:

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

int main(){

    char str1[32]="abcdefg";
    strcpy(str1+3,str1);
    printf("after copy, str1 = %s\n",str1);
    return 0;
}

拷贝后的空间和源字符串的空间是有重合的,则源字符串内容会被修改,运行结果为:

after copy, str1 = abcabcdefg

2. strncpy

原型:char *strncpy (char * __dest, const char *__src, size_t __n); 
功能:将一个字符串(__src)拷贝到另一个字符串缓冲区中(__dest),拷贝最多不超过__n字节,并返回拷贝后的字符串指针; 
例子:

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

int main(){

    const char* str1 = "allen junyu";
    char str2[32]="anything you can write";
    char* p=strncpy(str2,str1,7);
    printf("p=%s\n",p);
    p[7]=0;
    printf("p=%s\n",p);

    return 0;
}

运行结果:

p=allen jg you can write
p=allen j

注意: strncpy这个函数并不会自动的在字符串结尾加’\0’,需要我们去增加。

3. strcat

原型:char *strcat (char *__dest, const char *__src); 
功能:将一个字符串(__src)拼接到另一个字符串缓冲区中(__dest),并返回拼接后的字符串指针; 
例子:

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

int main(){
    char str1[32] = "allen";
    const char* str2 = "junyu";
    char* p=strcat(str1,str2);
    printf("p=%s\n",p);
    return 0;
}

运行结果:

p=allenjunyu

注意:同样地,需要保证str1有足够的存储空间,否则,程序会顺着内存地址往后写,破坏其他内存数据。

4. strncat

原型:char *strncat (char *__dest, const char *__src, size_t __n); 
功能:将一个字符串(__src)拼接到另一个字符串缓冲区中(__dest),最多不超过__n个字节,并返回拼接后的字符串指针; 
例子:

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

int main(){
    char str1[32]="allen ";
    const char* str2="junyu";

    strncat(str1,str2,3);
    printf("str1=%s,length=%d\n",str1,strlen(str1));
    strncat(str1,str2,1000000);
    printf("str1=%s,length=%d\n",str1,strlen(str1));

    return 0;
}

运行结果:

str1=allen jun,length=9
str1=allen junjunyu,length=14

5. strlen

原型:size_t strlen (const char *__s); 
功能:返回一个字符串(__src)的长度,即字节(符)数,这里仅考虑ASCII字符;

6. strcmp

原型: int strcmp (const char *__s1, const char *__s2); 
功能:比较字符串__s1和字符串__s2,返回比较结果,如果相等,则返回0; 
比较方式:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇’\0’为止; 
返回结果:当s1<s2时,返回值<0;当s1=s2时,返回值=0;当s1>s2时,返回值>0; 
例子:

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

int main(){

    const char* str1 = "allen junyu";
    char str2[32]="allen junyu";
    int ret = strcmp(str1,str2);
    printf("ret=%d\n",ret);

    return 0;
}

运行结果:

ret=0

7. strncmp

原型: int strncmp (const char *__s1, const char *__s2, size_t __n); 
功能:比较字符串__s1和字符串__s2__n个字符,返回比较结果,如果相等,则返回0; 
比较方式:同strcmp; 
返回结果:同strcmp; 
例子:

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

int main(){
    const char* str1 = "allen junyu";
    char str2[32]="allen bob";
    int ret = strncmp(str1,str2,5);
    printf("ret=%d\n",ret);
    return 0;
}

运行结果:

ret=0

8. strcasecmp

原型: int strcasecmp (const char *__s1, const char *__s2); 
功能:比较字符串__s1和字符串__s2,忽略大小写的比较,返回比较结果,如果相等,则返回0; 
例子:

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

int main(){

    const char* str1 = "allen";
    char str2[32]="AlleN";

    int ret = strcasecmp(str1,str2);
    printf("strcasecmp ret=%d\n",ret);

    return 0;
}

运行结果:

strcasecmp ret=0

9. strncasecmp

原型: int strncasecmp (const char *__s1, const char *__s2, size_t __n); 
功能:比较字符串__s1和字符串__s2__n个字符,忽略大小写的比较,返回比较结果,如果相等,则返回0; 
例子:

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

int main(){

    const char* str1 = "allen";
    char str2[32]="AlleN junyu";

    int ret = strncasecmp(str1,str2,5);
    printf("strncasecmp ret=%d\n",ret);

    return 0;
}

运行结果:

strncasecmp ret=0

10. strchr

原型:const char *strchr (const char *__s, int __c); 
功能:在字符串(__src)中查找字符__c首次出现的位置,并返回指向该位置的字符串指针,若没有这个字符,则返回NULL; 
例子:

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

int main(){
    const char* str1 = "allen";
    const char* p=strchr(str1,'l');
    printf("strchr p=%s\n",p);
    return 0;
}

运行结果:

strchr p=llen

注意:它只查找第一次出现,并且是返回指向位置的指针,而并不是返回位置;

11. strrchr

原型:const char *strrchr (const char *__s, int __c); 
功能:在字符串(__src)中反向查找字符__c首次出现的位置,并返回指向该位置的字符串指针,若没有这个字符,则返回NULL; 
例子:

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

int main(){
    const char* str1 = "allen";
    const char* p=strrchr(str1,'l');;
    if(p==NULL){
        printf("strrchr p=NULL\n");
    }else{
        printf("strrchr p=%s\n",p);
    }
    return 0;
}

运行结果:

strrchr p=len

12. strstr

原型:const char *strstr (const char *__haystack, const char *__needle); 
功能:在字符串(__haystack)中查找字符串__needle首次出现的位置,并返回指向该位置的字符串指针,若没有这个字符,则返回NULL; 
例子:

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

int main() {
    const char* str1 = "allen bigjunyu";
    const char* p = strstr(str1, "big");
    if (p == NULL) {
        printf("strstr p=NULL\n");
    } else {
        printf("strstr p=%s\n", p);
    }

    p = strstr(str1, "bigz");
    if (p == NULL) {
        printf("strstr p=NULL\n");
    } else {
        printf("strstr p=%s\n", p);
    }
    return 0;
}

运行结果:

strstr p=bigjunyu
strstr p=NULL

13. strpbrk

原型:const char *strpbrk (const char *__s, const char *__accept); 
功能:在字符串(__s)中查找字符串__needle中包含的字符集合的任意元素,返回这个任意字符的首次出现的位置,若任何字符,则返回NULL;注意,这个命名很怪异,不像前面的容易记住,这里pbrk的含义应该是”point break”遇到第一个匹配点就返回; 
例子:

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

int main() {
    const char* str1 = "allen bigjunyu";
    const char* str2 = "zmg";
    const char* p = strpbrk(str1, str2);
    if (p == NULL) {
        printf("strpbrk p=NULL\n");
    } else {
        printf("strpbrk p=%s\n", p);
    }
    return 0;
}

运行结果:

strpbrk p=gjunyu

14. strspn

原型:size_t strspn (const char *__s, const char *__accept); 
功能:以字符串(__accept)中字符作为集合,在字符串__s中查找不属于这个集合的第一个字符的位置并返回,若不存在,则返回整个字符串最后一个字符位置+1;注意,这个命名怪异,这里strspn的含义应该是”string span”的意思; 
例子:

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

int main() {
    const char* str1 = "allen junyu";
    const char* str2 = "alg";
    int idx = strspn(str1, str2);
    printf("strspn idx=%d\n",idx);
    return 0;
}

运行结果:

strspn idx=3

注意:ubuntu系统上的注释是Return the length of the initial segment of S which consists entirely of characters in ACCEPT.返回一个初始分割点,使得分割点之前的字符完全由ACCEPT中字符组成,跟上面所述的功能是一样的意思,而且这种注释也好理解一些。

15. strcspn

原型:size_t strcspn (const char *__s, const char *__reject); 
功能:以字符串__reject中字符作为集合,在字符串__s中查找属于这个集合的第一个字符的位置并返回,若不存在,则返回整个字符串最后一个字符位置+1;可理解为,在__s中寻找第一个分割点,使得分割点之前的字符串完全由非__reject中字符组成; 
例子:

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

int main() {
    const char* str1 = "allen junyu";
    const char* str2 = "xn";
    int idx = strcspn(str1, str2);
    printf("strcspn idx=%d\n",idx);
    return 0;
}

运行结果:

strcspn idx=4

注意:ubuntu系统上的注释是Return the length of the initial segment of S which consists entirely of characters not in REJECT.

15. strsep

原型:char *strsep (char** __stringp, const char* __delim); 
功能:以字符串__delim作为分隔符,在字符串__stringp寻找分隔符,找到第一个分隔符后,将分隔符位置设置为'\0',返回指向分隔符下一个字符,并设置__stringp所指向的字符串指针的指也指向这个位置,若不存在,则返回NULL; 
例子:

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

int main() {
    int len, nel;
    char query[] = "user_command=appleboy&test=1&test2=2";
    char *q, *name, *value;

    q = query;
    printf("string is : %s\n", query);
    len = strlen(query);
    nel = 0;
    while (strsep(&q, "&")){
        nel++;
        printf("now q=%s\n",q);
    }
    printf("number of elements : %d\n", nel);
    int gap;
    for (q = query; q < (query + len);) {
        printf("pair str :%s\n", q);
        value = name = q;
        gap = strlen(q)+1;
        /* Assign variable */
        name = strsep(&value, "=");
        printf("key:%s value:%s\n",name,value);
        q+=gap;
    }
    return 0;
}

运行结果:

string is : user_command=appleboy&test=1&test2=2
now q=test=1&test2=2
now q=test2=2
now q=(null)
number of elements : 3
pair str :user_command=appleboy
key:user_command value:appleboy
pair str :test=1
key:test value:1
pair str :test2=2
key:test2 value:2

注意:该函数会更改*__stringp的值,并且更改原始字符串的值,所以是char*而非const char*

15. strtok

原型:char *strtok (char* __s, const char* __delim); 
功能:以字符串__delim中字符作为分隔符集合,在字符串__s中查找,返回由分隔符分割的第一个单词指针,若没有,则返回NULL;当__s为NULL时,即继续上一次分割; 
例子:

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

int main() {
    char str[] = "babybaby&test=1&test2=2";
    const char* p;
    p = strtok(str, "&=");
    printf("str=%s,p=%s\n", str, p);
    while (p) {
        p = strtok(NULL, "&=");
        printf("str=%s,p=%s\n", str, p);
    }
    return 0;
}

运行结果:

str=babybaby,p=babybaby
str=babybaby,p=test
str=babybaby,p=1
str=babybaby,p=test2
str=babybaby,p=2
str=babybaby,p=(null)

注意:由于该函数具有缓存上次传入字符串的功能,其实是通过一个静态缓冲区来实现,所以是非线程安全的。这个函数在Linux下有线程安全版本strtok_r,更深入的论述,可以参考这篇文章STRTOK函数和STRTOK_R函数

16. 判断字符的函数集

原型均为:int name (int)类型 ,返回0表示“否”,其他表示“是” 
isalpha() 检查是否为字母字符 
isupper() 检查是否为大写字母字符 
islower() 检查是否为小写字母字符 
isdigit() 检查是否为数字 
isxdigit() 检查是否为十六进制数字表示的有效字符 
isspace() 检查是否为空格类型字符 
iscntrl() 检查是否为控制字符 
ispunct() 检查是否为标点符号 
isalnum() 检查是否为字母和数字 
isprint() 检查是否是可打印字符 
isgraph() 检查是否是图形字符,等效于 isalnum() | ispunct()

注意:需要包含的头文件为#include <ctype.h>

17. 数值字符串转成数值型函数集

int atoi(const char* p) 字符串转换到 int 整型 
double atof(const char* p) 字符串转换到 double 符点数 
long atol(const char* p) 字符串转换到 long 整型

注意:需要包含的头文件为#include <stdlib.h>,另外,如果是非对应类型的字符串,各自也会返回一个值,所以需要保证是数值字符串,否则无法判断是否正确转换。

18. 字符串转成数值型函数集

原型:double strtod (const char* __nptr, char ** __endptr); 
功能:从字符串 __nptr 中转换 double 类型数值,并将后续的字符串指针存储到 __endptr指向的 char* 类型存储 
例子:

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

#include <ctype.h>
#include <stdlib.h>

int main() {
    char str[]="123.245junyu";
    char buffer[16];
    char* p=buffer;

    double x=strtod(str,&p);
    printf("strtod x=%f,p=%s\n",x,p);
    return 0;
}

运行结果:

strtod x=123.245000,p=junyu

原型:long int strtol (const char* __nptr, char** __endptr, int __base); 
功能:从字符串__nptr 中转换 long 类型整型数值,__base 显式设置转换的整型进制,设置为 0 以根据特定格式判断所用进制; 
例子:

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

#include <ctype.h>
#include <stdlib.h>

int main() {
    char str[]="123.goodjunyu";
    char buffer[16];
    char* p=buffer;

    long x=strtol(str,&p,0);
    printf("strtol x=%ld,p=%s\n",x,p);
    return 0;
}

运行结果:

strtol x=123,p=.goodjunyu

注意:需要包含头文件#include <stdlib.h>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值