第七章 字符串处理函数

第七章 字符串处理函数

7.1 获取字符串长度函数

头文件:#include <string.h>

函数定义:size_t strlen(const char *s)

函数功能:

测字符指针s指向的字符串中字符的个数,不包括’\0’

**返回值:**字符串中字符个数

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

int main(int argc, char const *argv[])
{
    // 使用strlen()函数获取字符串的长度
    // strlen()获取的字符串的长度遇到第一个\0结束
    char s1[100] = "hel\0lo world!";
    printf("s1_len = %lu\n", strlen(s1));
    printf("s1_size = %lu\n", sizeof(s1));

    char *s2 = "hel\0lo world!";
    printf("s2_len = %lu\n", strlen(s2));
    printf("s2_size = %lu\n", sizeof(s2));
    return 0;
}

执行结果:

image-20221023204300731

7.2 字符串拷贝函数

头文件:#include <string.h>

函数的定义:char *strcpy(char *dest, const char *src);

函数的说明:

拷贝src指向的字符串到dest指针指向的内存中,'\0’也会被拷贝

函数的返回值:

目的内存的地址

**注意:**在使用此函数的时候,必须保证dest指向的内存空间足够大,否则会出现内存污染

函数的定义:char *strncpy(char *dest, const char *src, size_t n);

函数的说明:

将src指向的字符串前n个字节,拷贝到dest指向的内存中

返回值:

目的内存的首地址

注意:

  1. strncpy不拷贝’\0’
  2. 如果n大于src指向的字符串中的字符个数,则在dest后面填充n-strlen(src)个’\0’
#include <stdio.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    // 使用strcpy()函数拷贝字符串
    char s1[32] = "hello world";
    // 使用strcpy函数时,必须保证第一个函数的参数的内存足够大
    char s1[5] = "hello";
    char s2[32] = "abcdefg";


    strcpy(s1, s2);
    printf("s1 = %s\n", s1);

    for (size_t i = 0; i < 32; i++)
    {
        printf("[%c] -- %d\n", s1[i], s1[i]);
    }
    
    return 0;
}

执行结果:

截屏2022-10-23 21.55.59

7.3 字符串追加函数

头文件:#include <string.h>

函数定义:char *strcat(char *dest, const char *src);

函数功能:

strcat函数追加src字符串到dest指向的字符串的后面,追加的时候会追加’\0’

注意:

保证dest指向的内存空间足够大

函数定义:char *strncat(char *dest, const char *src, size_t n);

函数功能:

追加src指向的字符串的前n个字符,到dest指向的字符串的后面

注意:

如果n大于src的字符个数,则只将src字符串追加到dest指向的字符串的后面,追加的时候会追加’\0’

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

int main(int argc, char const *argv[])
{
    // 使用strcat函数追加字符串
    char s1[32] = "hello world";
    char s2[32] = "abcdef";

    // strcat是从s1的\0的位置开始追加,直到s2的第一个\0复制完毕后结束
    strcat(s1, s2);
    printf("s1 = %s\n", s1);
    return 0;
}

执行结果:

截屏2022-10-23 22.27.40

7.4 字符串比较函数

头文件:#include <string.h>

函数定义:int strcmp(const char *s1, const char *s2);

函数说明:

比较s1和s2指向的字符串的大小

比较的方法,逐个字符去比较ascll码,一旦比较出大小返回,如果所有字符都一样,返回0

返回值:

比较结果返回值
s1指向的字符串大于s2指向的字符串1
s1指向的字符串等于s2指向的字符串0
s1指向的字符串小于s2指向的字符串-1

函数定义:int strncmp(const char *s1, const char *s2, size_t n);

函数说明:

比较s1和s2指向的字符串中的前n个字符

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

int main(int argc, char const *argv[])
{
    // 使用strcmp函数比较两个字符串的内容是否一致
    // strcmp函数一个字符一个字符比较,只要出现不一样的,就会立即返回
    char s1[] = "hello";
    char s2[] = "hello";

    int ret = strcmp(s1, s2);

    if (ret ==0)
    {
        printf("s1 = s2\n");
    }
    else if (ret > 0)
    {
        printf("s1 > s2\n");
    }
    else
    {
        printf("s1 < s2\n");
    }
    return 0;
}

执行结果:

截屏2022-10-23 22.46.37

7.5 字符串查找函数

头文件:#include <string.h>

函数定义: char *strchr(const char *s, int c);

函数说明:

在字符指针s指向的字符串中,找ascii码为c的字符。

注意:

是首次匹配,如果说s指向的字符串中有多个ascll为c的字符,则找的是第一个字符

返回值:

  • 找到了,返回找到的字符的地址
  • 找不到,返回NULL

函数定义:char *strrchr(const char *s, int c);

函数说明:

末次匹配,在s指向的字符串中,找最后一次出现ascll为c的字符

返回值:

末次匹配字符的地址

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

int main(int argc, char const *argv[])
{
    // 使用strchr函数中一个字符串中查找字符
    char s[] = "hel6lo wor6ld";
    char *ret = strchr(s, '6');

    if (ret == NULL)
    {
        printf("没有找到\n");
    }
    else
    {
        printf("找到了,在数组的第%ld个位置\n", ret - s);
    }
    return 0;
}

执行结果:

截屏2022-10-23 23.05.19

7.6 字符串匹配函数

头文件:#include <string.h>

函数定义: char *strstr(const str *haystack, const char *needle);

函数说明:

在haystack指向的字符串中查找needle指向的字符串,也是首次匹配

返回值:

  • 找到了,找到的字符串的首地址
  • 没找到,返回NULL
#include <stdio.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    // 使用strstr函数在一个字符串中查找另一个字符串
    char s[] = "1234:4567:666:789:666:7777";

    // strstr查找的时候,查找的是第二个参数的第一个\0之前的内容
    char *ret = strstr(s, "666");
    if (ret == NULL)
    {
        printf("没找到\n");
    }
    else
    {
        printf("找到了,在第%ld个位置\n", ret -s);
    }
    return 0;
}

7.7 字符串转换数值

头文件:#include <stdlib.h>

函数定义1:int atoi(const char *nptr);

函数定义2:long atol(const char *nptr);

函数定义3:double atof(const char *nptr);

函数的功能:

将nptr指向的字符串转换整数并返回

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    // 使用atoi将数字型字符串转换为整形数据
    char s1[] = "7896";
    int ret1 = atoi(s1);

    printf("ret1 = %d\n", ret1);

    // 使用atof将浮点型字符串转化为浮点型数据
    char s2[] = "3.1415926";
    double ret2 = atof(s2);

    printf("ret2 = %lf\n", ret2);
    return 0;
}

7.8 字符串切割函数

头文件:#include <string.h>

函数定义:*strtok(char *str, const char *delim);

函数功能:

对字符串进行切割

参数:

  • str:要切割的字符串。第一次切割,就传入的指定的字符串,后面所有次的切割传NULL
  • delim:标识符。要根据指定的delim进行切割,切割的结果不包含delim

返回值:

返回切割下来的字符串的首地址,如果都切割完毕,则返回NULL

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

int main(int argc, char const *argv[])
{
    // 使用strtok函数切割字符串
    char s[] = "1111:22:3333:44:555";
    char *ret;
    // 第一次切割
    ret = strtok(s, ":");
    printf("ret = %s\n", ret);

    // 后面所有的切割时,都要将strtok的第一个参数传NULL
    while((ret = strtok(NULL, ":")) != NULL)
        printf("ret = %s\n", ret);
    return 0;
}

执行结果:

image-20221023235201140

7.9 格式化字符串操作函数

函数定义:int sprintf(char *buf, const char *format, ...);

**函数功能:**输出到buf指定的内存区域

例如:

char buf[20];
sprintf(bufm "%d:%d:%d", 2013, 10, 1);
printf("buf=%s\n", buf);

函数定义:int sscanf(const char *buf, const char *format, ...);

**函数功能:**从buf指定的内存区域读入信息

例如:

sscanf("2013:10:1", "%d:%d:%d", &a, &b, &c);
printf("%d %d %d\n", a, b, c);
#include <stdio.h>
#include <string.h>

void test1()
{
    char buf[20];
    int a, b, c;

    sprintf(buf, "%d:%d:%d", 2013, 10, 1);
    printf("buf = %s\n", buf);

    sscanf("2013:10:1", "%d:%d:%d", &a, &b, &c);
    printf("a=%d, b=%d, c=%d\n", a, b, c);
}


// sscanf()高级用法
void test2()
{
    // 1. 跳过数据:%*s或 %*d
    char buf1[20];
    sscanf("1234 5678", "%*d %s", buf1);
    printf("%s\n", buf1);

    // 2. 读指定宽度的数据: %[width]s
    char buf2[20];
    sscanf("12345678", "%4s", buf2);
    printf("%s\n", buf2);

    // 3. 支持集合操作:只支持获取字符串
    //    %[a-z]        表示匹配到a到z中任意字符,尽可能多的匹配
    //    %[aBc]        表示匹配a、B、c中的一员,贪婪性
    //    %[^aBc]       表示非a、B、c的任意字符,贪恋性
    //    %[^a-z]       表示读取除a-z以外的所有字符
    char buf3[30];
    sscanf("agcd32DajfDdFF", "%[a-z]", buf3);
    printf("%s\n", buf3);

}

int main(int argc, char const *argv[])
{
    test1();   
    test2();
    return 0;
}

执行结果:

image-20221024002954721

7.10 const

  1. const修饰普通变量,代表只读的意思

const int a = 100; //定义了一个只读变量a值为100

以后的程序里,不能再给a赋值了

a = 200; // 错误的,a只读

const修饰全局变量

#include <stdio.h>

// const 修饰全局变量
const int a = 100;
void test1()
{
    // 此时全局变量只能使用,但是不能修改
    printf("a = %d\n", a);

    // 如果直接拿全局变量修改值,编译直接报错
    a = 666;
    printf("a = %d\n", a);

    // 如果使用全局变量的地址修改值,运行时程序异常结束
    int *p = &a;
    *p = 888;
    printf("a = %d\n", a);

}

int main(int argc, char const *argv[])
{
    test1();
    return 0;
}

a. 此时全局变量可以直接使用

image-20221024224527382

b. 如果直接拿全局变量修改值,编译直接报错

image-20221024224641020

c. 如果使用全局变量的地址修改值,运行时程序异常结束

image-20221024224742120

const修饰普通局部变量:

#include <stdio.h>

// const 修饰局部变量
void test2()
{
    // 可以读取变量的值
    const int b = 100;
    printf("b = %d\n", b);

    // 不能直接通过变量进行修改值,编译报错
    b = 666;
    printf("b = %d\n", b);

    // 可以通过变量的地址修改值
    int *p = &b;
    *p =  888;
    printf("b = %d\n", b);

}

int main(int argc, char const *argv[])
{
    test2();
    return 0;
}

a. 可以直接读取变量的值

image-20221024225428826

b. 不能直接通过变量进行修改值,会编译报错

image-20221024225619221

c. 可以通过变量的地址修改值(但是存在警告“警告:使用类型为“const int *”的表达式初始化“int *”将丢弃限定符”)

image-20221024225725827

  1. const修饰指针
  • const char *str,意思是str指向的内存的内容不能通过str来修改

用来保护str指向的内存的内容,但是str的指向是可以改变的

例如:char *strcpy(char *dest, const char *src);

#include <stdio.h>
// const修饰指针变量
void test3()
{
    int c = 100;
    // const修饰指针变量的类型,无法通过指针变量修改地址里面的值
    const int *p = &c;
    // const修饰指针变量,无法修改指针变量保存的地址
    int * const p1 = &c;
    // const既修饰指针变量的类型,又修饰指针变量,只能通过修改原本变量修改值
    const int * const p2 = &c;
    printf("*p = %d, *p1 = %d, *p2 = %d\n", *p, *p1, *p2);

    c = 666;
    printf("*p = %d, *p1 = %d, *p2 = %d\n", *p, *p1, *p2);

    // *p = 777;
    *p1 = 777;
    printf("*p1 = %d\n", *p1);
    *p2 = 777;
    printf("*p = %d, *p1 = %d, *p2 = %d\n", *p, *p1, *p2);

    int d = 888;
    p = &d;
    printf("*p = %d\n", *p);
    p1 = &d;
    p2 = &d;
    printf("*p = %d, *p1 = %d, *p2 = %d\n", *p, *p1, *p2);

}
int main(int argc, char const *argv[])
{
    test3();
    return 0;
}
  • const修饰指针变量的类型,无法通过指针变量修改地址里面的值
#include <stdio.h>
// const修饰指针变量
void test3()
{
    int c = 100;
    // const修饰指针变量的类型,无法通过指针变量修改地址里面的值
    const int *p = &c;
    printf("*p = %d\n", *p);

    c = 666;
    printf("*p = %d\n", *p);

    *p = 777;
    printf("*p = %d\n", *p);

    int d = 888;
    p = &d;
    printf("*p = %d\n", *p);

}
int main(int argc, char const *argv[])
{
    test3();
    return 0;
}

image-20221024231622611

  • const修饰指针变量,无法修改指针变量保存的地址
#include <stdio.h>
// const修饰指针变量
void test3()
{
    int c = 100;
    // const修饰指针变量,无法修改指针变量保存的地址
    int * const p1 = &c;
    printf("*p1 = %d\n", *p1);

    c = 666;
    printf("*p1 = %d\n", *p1);

    *p1 = 777;
    printf("*p1 = %d\n", *p1);

    int d = 888;
    p1 = &d;
    printf("*p1 = %d\n", *p1);

}
int main(int argc, char const *argv[])
{
    test3();
    return 0;
}

image-20221024231933672

  • const既修饰指针变量的类型,又修饰指针变量,只能通过修改原本变量修改值
#include <stdio.h>
// const修饰指针变量
void test3()
{
    int c = 100;
    // const既修饰指针变量的类型,又修饰指针变量,只能通过修改原本变量修改值
    const int * const p2 = &c;
    printf("*p2 = %d\n", *p2);

    c = 666;
    printf("*p2 = %d\n", *p2);

    *p2 = 777;
    printf("*p2 = %d\n", *p2);

    int d = 888;
    p2 = &d;
    printf("*p2 = %d\n", *p2);

}
int main(int argc, char const *argv[])
{
    test3();
    return 0;
}

image-20221024232153528

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王山之

天青色等烟雨~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值