C和指针学习笔记(二)——字符串常用库函数

这个系列主要是我学习《C和指针》这本书的一些笔记,主要关于一些小的细节,目的是供自己学习和参考,详细地部分建议大家可以阅读一下《C和指针》这本书


字符串长度

库函数 strlen 的原型如下:

size_t strlen( char const *string );

注意 strlen 返回一个类似为 size_t 的值。这个类型是在头文件 stddef.h 中定义的,它是一个无符号整数类型。在表达式中使用无符号数可能导致不可预料的结果。例如,下面两个表达式看上去是相等的:

if( strlen( x ) >= strlen( y ) ) ...
if( strlen( x ) - strlen( y ) >= 0 ) ...

但事实上它们是不相等的。第 1 条语句将按照你预想的那样工作,但第 2 条语句的结果将永远是真。strlen 的结果是个无符号数,所以操作符 >= 左边的表达式也将是无符号数,而无符号数绝不可能是负的。
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    char s[] = "123456";
    printf("%d\n", strlen(s)); //输出6
    return 0;
}

不受限制的字符串函数

最常用的字符串都是 “不受限制” 的,也就是说它们只是通过寻找字符串参数结尾的 NUL 字节来判断它的长度,这些函数一般都指定一块内存用于存放结果字符串。在使用这些函数时,程序员必须保证结果字符串不会溢出这块内存。

复制字符串

用于复制字符串的函数是 strcpy ,它的原型如下所示:

char *strcpy( char *dst, char const *src );

这个函数把参数 src 字符串复制到 dst 参数,返回结果为一个指向目标字符数组的指针。如果参数 srcdst 在内存中出现重叠,其结果是未定义的。由于 dst 参数将进行修改,因此它必须是个字符数组或者是一个指向动态分配内存的数组的指针,不能使用字符串常量。
需要注意目标字符数组的空间足以容纳需要复制的字符串。否则将会覆盖数组后面的内存空间的值。
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    char s1[] = "123456";
    char s2[] = "890";
    strcpy(s1, s2);
    int i;
    for(i=0; s1[i]; ++i)
        printf("%c", s1[i]); //输出 890
    return 0;
}


连接字符串

要想把一个字符串添加(连接)到另一个字符串的后面,可以使用 strcat 函数。它的原型如下:

char *strcat( char *dst, char const *src );  

strcat函数要求 dst 参数原先已经包含了一个字符串(可以是空字符串)。它找到这个字符串的末尾,并把 src 字符串的一份副本添加到这个位置,返回结果为指向目标字符数组的指针。如果 srcdst 的位置发生重叠,其结果是未定义的。
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    char s1[100] = "123456";
    char s2[] = "890";
    strcat(s1, s2);
    for(int i=0; s1[i]; ++i)
        printf("%c", s1[i]); //输出 1234567890
    return 0;
}


字符串比较

库函数 strcmp 用于比较两个字符串,它的原型如下:

int strcmp( char const *s1, char const *s2 );

如果 s1 小于 s2strcmp函数返回一个小于零的值;如果 s1 大于 s2,函数返回一个大于零的值;如果两个字符串相等,函数就返回零。
注意这里是词典比较,且相等是输出 0 而不是 1
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    char s1[100] = "123456";
    char s2[] = "890";
    printf("%d\n", strcmp(s1, s2)); //输出 -1
    return 0;
}

长度受限的字符串函数

标准库还包含了一些函数,它们以一种不同的方式处理字符串。这些函数接受一个显式的长度参数,用于限定进行复制或比较的字符数。这些函数提供了一种方便的机制,可以防止难以预料的长字符串从它们的目标数组溢出。
这些函数的原型如下:

char *strncpy( char *dst, char const *src, size_t len );
char *strncat( char *dst, char const *src, size_t len );
int strncmp( char const *s1, char const *s2, size_t len );

strcpy 一样,strncpy把源字符串的字符复制到目标数组。然而,它总是正好向 dst 写入 len 个字符。如果 strlen( stc ) 的值小于 lendst 数组就用额外的 NUL 字节填充到 len 长度;如果 strlen( src ) 的值大于或等于 len,那么只有 len 个字符被复制到 dst 中。注意!它的结果将不会以 NUL 字节结尾。


字符串查找函数

查找一个字符

在一个字符串中查找一个特定字符最容易的方法是使用 strchrstrrchr 函数,它们的原型如下所示:

char *strchr( char const *str, int ch );
char *strrchr( char const *str, int ch );

注意,它们的第 2 个参数是一个整型值。但是,它包含了一个字符值。strchr 在字符串 str 中查找字符 ch1 次出现的位置,找到后函数返回一个指向该位置的指针。如果该字符并不存在于字符串中,函数就返回一个 NULL 指针。 strrchr 的功能和 strchr 基本一致,只是它所返回的是一个指向字符串该字符最后一次出现的位置(最右边那个)。
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    char string[20] = "Hello there, honey.";
    char *ans;

    ans = strchr( string, 'h');
    while(*ans)
        printf("%c", *ans++); //输出 here, honey.
    return 0;
}


查找任何几个字符

strpbrk 是个更为常见的函数。它并不是查找某个特定的字符,而是查找任何一组字符第一次在字符串中出现的位置。它的原型如下:

char *strpbrk( char const *str, char const *group );

这个函数返回一个指向 str 中第 1 个匹配 group 中任何一个字符的字符位置。如果未找到匹配,函数返回一个 NULL 指针。
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    char string[20] = "Hello there, honey.";
    char *ans;

    ans = strpbrk( string, "aeiou");
    while(*ans)
        printf("%c", *ans++); //输出 ello there, honey.
    return 0;
}


查找一个子串

为了在字符串中查找一个子串,可以使用 strstr 函数,它的原型如下:

char *strstr( char const *s1, char const *s2 ); 

这个函数在 s1 中查找整个 s2 第一次出现的起始位置,并返回一个指向该位置的指针。如果 s2 并没有完整地出现在 s1 的任何地方,函数将返回一个 NULL 指针。如果第 2 个参数是一个空字符串,函数就返回 s1


查找一个字符串前缀

strspnstrcspn 函数用于在字符串的起始位置对字符计数。它们的原型如下所示:

size_t strspn( char const *str, char const *group );
size_t strcspn( char const *str, char const *group );

group 字符串指定一个或多个字符。strspn返回 str起始部分匹配 group 中任意字符的字符数。
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    int len1, len2;
    char buffer[] = "25,142,330,Smith,J,239-4123";
    len1 = strspn( buffer, "0123456789" ); // 2
    len2 = strspn( buffer, ",0123456789"); // 11
    printf("%d %d\n", len1, len2 ); // 输出 2 11
    return 0;
}


查找标记

strtok函数从字符串中隔离各个单独的称为标记( token )的部分,并丢弃分隔符。它的原型如下:

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

sep 参数是个字符串,定义了用作分隔符的字符集合。第 1 参数指定一个字符串,它包含零个或多个由 sep 字符串中一个或多个分隔符分隔的标记。strtok 找到 str 的下一个标记,并将其用 NUL 结尾,然后返回一个指向这个标记的指针。
一个栗子

#include <stdio.h>
#include <string.h>
int main()
{
    char whitespace[] = " \t\f\r\v\n";
    char *token;
    char line[] = "Hello, nice to meet you.";
    for( token = strtok( line, whitespace );
        token != NULL;
        token = strtok( NULL, whitespace))
        printf("Next token is %s\n", token );
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值