11_字符串操作函数

字符串操作函数

以str开头的函数 都是字符串操作函数 都是遇到 '\0' 结束操作

strlen 测量字符串长度

#include<string.h>
size_t strlen(const char *s);
s: 需要测量字符串的首元素地址
char str[128]="hello";
strlen(str); //5

strcpy 字符串拷贝函数

#include <string.h>
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
src 拷贝到 dest
n: src要拷贝的字符数
返回值: dest首地址

image-20230801164133290

strcat 字符串追加函数

#include <string.h>
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);
src 追加到 dest 后面
n: 要追加的src的字符数
返回值: dest 首地址

image-20230801164912769

strcmp 字符串比较

#include <string.h>
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
返回值: >0 s1>s2
  		 <0 s1<s2
  		 =0 s1=s2

strchr 字符查找函数

#include <string.h>
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
strchr 第一次出现c的地址, 如果没找到 返回 NULL
strrchr 最后一次出现c的地址, 如果没找到 返回 NULL

image-20230801230342815

strstr 字符串查找

#include <string.h>
char *strstr(const char *haystack, const char *needle);
返回第一次找到needle的首地址, 没找到返回 NULL

image-20230801231551155

字符串转数值

#include <stdlib.h>
atoi: 将字符串转成 int
"100" ===> 100
"sdj125df" ===> 0
"123sdlkfj651" ===> 123
atoi: 将字符串转成long
atof: 将字符串转成float

image-20230802001244554

strtok 字符串切割

#include <string.h>
char *strtok(char *str, const char *delim);
str按delim进行切割
delim: ";:#", 将按照';', ':', '#'单独分割, 不分顺序
第一次切: 用strtok(str, delim); 切成功返回首地址,否则返回NULL
后续切: 第一次切不为NULL, 用strtok(NULL, delim); 切成功返回首
地址,否则返回NULL
//不能char *str = "sdfjlk:sdjfhj"; 字符常量区':'不能替换成'\0'
    char str[] = "sdfjlk:sdjfhj:ksjdhuio:sdjhf:jkncvk:sdfu";
    char *buff[32] = {0}; //存放子串首地址

    //第一次切
    int i = 0;
    buff[i] = strtok(str, ":");

    //后续切
    while (buff[i] != NULL)
    {
        i++;
        buff[i] = strtok(NULL, ":");
    }

    for (int i = 0; buff[i] != NULL; i++)
    {
        printf("%s ", buff[i]);
    }
    printf("\n");

格式化字符串

组包: 按照需要的格式 组成字符串

解包: 解析特定格式的数据

sprintf 用于组包

#include <stdio.h>
int sprintf(char *str, const char *format, ...);
类似于: printf(const char *format, ...); 只是没有 char *str
str: 组包存放位置
返回值: 实际组包长度

image-20230803151050739

image-20230803151215509

sscanf 解包

#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
str: 源数据
format: 解析格式
...: 解析到哪里

image-20230803152113603

%d提取数值 '0' ~ '9'

%s提取字符串 遇到 '\0' 空格 回车 换行 结束

sscanf 高级用法

跳过数据

//跳过数据 %*d %*s
sscanf("1234 5678", "%*d %s", buf); //buf="5678"

%[width]d %[width]s 读取指定宽度的数据

image-20230803234127825

%[aBc] 匹配aBc中的一个

image-20230804171131261

注意: 如果第一个字符匹配, 第二个字符不匹配就结束

%[a-z] 表示匹配a-z中任意字符

image-20230804170655564

%[a-z,A-Z] 匹配a-z, A-Zimage-20230804170816041

%[ ^aFc ] 匹配aFc的任意字符

image-20230805150001351

image-20230805150718540

例子: 提取信息

char buf[] = "+CMGR:REC UNREAD,+861346630259,98/10/01,18:22:11+00,ABCdefGHI";
    char *msg[32] = {buf};

    int i=0;
    while ((msg[i] = strtok(msg[i], ",")) && ++i);

    //短信状态读取
    char status[128] = "";
    sscanf(msg[0], "%*s %s", status);
    if (strcmp(status, "UNREAD") == 0)
    {
        printf("有未读消息\n");
    }
    else if (strcmp(status, "READ") == 0)
    {
        printf("已读消息\n");
    }
    
    //获取电话
    printf("电话: %s\n", msg[1] + 3);

    //日期
    int year = 0;
    int month = 0;
    int day = 0;
    sscanf(msg[2], "%d/%d/%d", &year, &month, &day);
    printf("日期: %02d年%02d月%02d日\n", year + 1900, month, day);
    
    //时间
    int h = 0;
    int m = 0;
    int s = 0;
    sscanf(msg[3], "%d:%d:%d", &h, &m, &s);
    printf("时间: %02d时%02d分%02d秒\n", h, m, s);

    //消息
    printf("消息: %s\n", msg[4]);

image-20230805153830361

const

const修饰普通变量为只读变量

//num为只读,只能初始化,不能赋值
const int num = 10;
num = 100; //报错
printf("%d\n", num);

const修饰*

int num = 10;
const int *p = &num;
*p: 只读
num: 可读可写
p: 可读可写

const既修饰*也修饰指针变量

const int * const p = &num;
第一个const: 修饰*
第二个const: 修饰p
*p: 只读
p: 只读
num: 可读可写
posted @ 2023-08-05 23:30  爱吃冰激凌的黄某某  阅读(15)  评论(0编辑  收藏  举报