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首地址
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 首地址
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
strstr 字符串查找
#include <string.h>
char *strstr(const char *haystack, const char *needle);
返回第一次找到needle的首地址, 没找到返回 NULL
字符串转数值
#include <stdlib.h>
atoi: 将字符串转成 int
"100" ===> 100
"sdj125df" ===> 0
"123sdlkfj651" ===> 123
atoi: 将字符串转成long
atof: 将字符串转成float
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: 组包存放位置
返回值: 实际组包长度
sscanf 解包
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
str: 源数据
format: 解析格式
...: 解析到哪里
%d提取数值 '0' ~ '9'
%s提取字符串 遇到 '\0' 空格 回车 换行 结束
sscanf 高级用法
跳过数据
//跳过数据 %*d %*s
sscanf("1234 5678", "%*d %s", buf); //buf="5678"
%[width]d %[width]s 读取指定宽度的数据
%[aBc] 匹配aBc中的一个
注意: 如果第一个字符匹配, 第二个字符不匹配就结束
%[a-z] 表示匹配a-z中任意字符
%[a-z,A-Z] 匹配a-z, A-Z![image-20230804170816041](https://img2023.cnblogs.com/blog/2387811/202308/2387811-20230805232957005-1910479365.png)
%[ ^aFc ] 匹配aFc的任意字符
例子: 提取信息
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]);
const
const修饰普通变量为只读变量
//num为只读,只能初始化,不能赋值
const int num = 10;
num = 100; //报错
printf("%d\n", num);
const修饰*
int num = 10;
const int *p = #
*p: 只读
num: 可读可写
p: 可读可写
const既修饰*也修饰指针变量
const int * const p = #
第一个const: 修饰*
第二个const: 修饰p
*p: 只读
p: 只读
num: 可读可写