吕梁网站建设,网站开发与设计 需求分析,自己建网站要学什么,投票网页制作教程字符串
1. 字符串处理函数
1. strlen#xff1a;长度
作用#xff1a;测量字符串长度
语法#xff1a; size_t strlen(const char *s);参数#xff1a; s#xff1a;要测量的字符指针变量 返回值#xff1a; 字符串长度 注意#xff1a;不包含 ‘\0’ sizeof 是个关…字符串
1. 字符串处理函数
1. strlen长度
作用测量字符串长度
语法 size_t strlen(const char *s);参数 s要测量的字符指针变量 返回值 字符串长度 注意不包含 ‘\0’ sizeof 是个关键字测量数据的 占用内存空间大小。 如果测量的是数组的名字则测的是数组占多少个字节如果 sizeof 测的是指针变量则测的是指针变量本身占几个字节 32 平台下结果为 4G strlen 是个库函数它测的是字符指针指向的字符串中字符的个数不管指针是数组的名字还是个指针变量。 示例
#include stdio.h
#include string.h
void fun01()
{char *str01 hell0;int len strlen(str01);printf(str01的长度为:%d\n, len);
}
int main(int argc, char const *argv[])
{fun01();return 0;
}
//str01的长度为:52. strcpy拷贝
语法 char *strcpy(char *dest, const char *src);参数 dest目标地址src要拷贝的字符串 返回值 目的内存地址 作用拷贝 src 指向的字符串到 dest 指针指向的内存中 ’\0’ 也会拷贝
注意 必须保证 dest 指向的内存空间足够大否则会出现内存污染要注意 拷贝与赋值的区别 示例1
#include string.h
#include stdlib.hvoid fun02()
{char *str01 hello world!;char *str02 (char *)malloc(strlen(str01) 1);if (str02 NULL){printf(内存开辟失败);return;}strcpy(str02, str01);printf(str02%s\n, str02);if (str02 ! NULL){free(str02);str02 NULL;}
}
int main(int argc, char const *argv[])
{fun02();return 0;
}
//str02hello world!示例2 拷贝与赋值的区别
void fun03()
{char str01[] hello;/*将str01的地址赋值给了str02此时不管str01还是str02对其进行修改,另外一个也将被修改*/char *str02 str01;str01[0] H;printf(str02%s\n,str02); //str02Hellostr02[1] E;printf(str01%s\n,str01); //str01HEllo
}void fun04()
{char str01[] hello;char *str02 (char *)malloc(strlen(str01) 1);/*strcpy会将str01的值拷贝一份给str02此时str01修改不会影响str02反之str02修改也不会影响str01*/strcpy(str02,str01);str01[0] H;printf(str02%s\n,str02); //str02hello
}3. strncpy拷贝前n个字节
语法 char *strncpy(char *dest, const char *src, size_t n);参数 dest目标地址src要拷贝的字符串 返回值 目的内存 的 首地址 作用将 src 指向的字符串前 n 个字节拷贝到 dest 指向的内存中
注意 不拷贝 ‘\0’如果 **n 大于 src **指向的字符串中的字符个数则在 dest 后面填充 n-strlen(src)个 ’\0’ 示例
void fun05()
{char *str01 hello;char *str02 (char *)calloc(5, 1);strncpy(str02, str01, 3);printf(str02%s\n, str02); //str02hel
}示例2
void fun06()
{int len,i,len02;char buf[100]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;lenstrlen(buf);printf(buf长度:%d\n,len); //buf长度:38strncpy(buf,helloworld,15); printf(buf%s\n,buf); //bufhelloworldlen02strlen(buf);printf(buf拷贝后长度:%d\n,len02); //buf拷贝后长度:10for(i0;ilen;i)printf(%c,buf[i]); printf(\n);//注意遍历后发现a还在字符串中 helloworldaaaaaaaaaaaaaaaaaaaaaaa只是字符串以 \0结尾长度和打印没显示
}4. strcat追加
语法 char *strcat(char *dest, const char *src);参数 dest目标地址src要追加的字符串 注意 会追加 ’\0’保证 dest 指向的内存空间足够大。 作用 追加 src 字符串到 dest 指向的字符串的后面。
示例
void fun08()
{char str01[100] hello;char str02[] world;strcat(str01,str02);printf(str01%s\n,str01); //str01helloworld
}5. strncat追加前n个字符
语法 char *strncat(char *dest, const char *src, size_t n);参数 dest目标地址src要追加的字符串n要追加字符的个数 注意 会追加 ’\0’如果 n 大于 src 的字符个数则只将 src 字符串追加到 dest 指向的字符串的后面追加的时候会追加’\0’ 。 作用 追加 src 字符串 的前n个字符 到 dest 指向的字符串的后面。
示例
void fun07()
{char str01[100] hello;char str02[] world;strncat(str01,str02, 3);printf(str01%s\n,str01); //str01hellowor
}6. strcmp比较
语法 int strcmp(const char *s1, const char *s2);参数 s1要比较的字符串1s2要比较的字符串2 作用比较 s1 和 s2 指向的字符串的大小
比较的方法逐个字符去比较 ascII 码一旦比较出大小返回。
返回值
返回 0 表示所有字符都一样返回 1 s1 指向的字符串大于 s2 指向的字符串返回-1 s1 指向的字符串小于 s2 指向的字符串
void fun10()
{char *str01 hello;char str02[100];strcpy(str02, str01);int num strcmp(str01, str02);if (num 0){printf(str01和str02相同\n);}else{printf(str01和str02不相同\n);}
}
//str01和str02相同7. strncmp比较前n个字符
比较 s1 和 s2 指向的字符串中的前 n 个字符
小练习示例
int fun11()
{/*用户输入账号与密码如果账号为admin,密码为123456显示登录成功否则显示登录失败*/for(int i 0; i 3; i){printf(请输入账号:\n);char uname[100];scanf(%s,uname);printf(请输入密码:\n);char pword[100];scanf(%s,pword);if (strcmp(uname,admin) 0 strcmp(pword,123456) 0){printf(登录成功\n);return 1;}else{printf(账号密码不匹配\n);if (2 - i 0){printf(账号已被锁定\n);}else{printf(还有%d次机会\n,(2-i));}}}return 0;
}8. strchr字符查找函 首次匹配
语法 char *strchr(const char *s, int c);参数 s字符串c要查的字符 作用在字符指针 s 指向的字符串中找 ascii 码为 c 的字符
注意 是首次匹配如果说 s 指向的字符串中有多个 AScII 为 c 的字符则找的是第 1 个字符 返回值
找到了返回 找到字符第一次出现的地址找不到返回 NULL。
示例
void fun11()
{char *str01 hello;char *p1 strchr(str01, l);if (p1 ! NULL){printf(p1%p\n, p1); //p10x400f46printf(o 的下标为:%ld\n, p1 - str01); //o 的下标为:2计算字符在字符串中的第一次出现的下标}}9. strrchr字符查找函 末次匹配
作用在 s 指向的字符串中找最后一次出现的 AScII 为 c 的字符
返回值末次匹配的字符的地址
示例
void fun12()
{char *str01 hello;char *p1 strrchr(str01, l);if (p1 ! NULL){printf(p1%p\n, p1); //p10x400ff7printf(o 的下标为:%ld\n, p1 - str01); //o 的下标为:3计算字符在字符串中的第一次出现的下标}}10. strstr 字符串匹配 首次匹配
语法 char *strstr(const char *haystack, const char *needle);参数 haystack被匹配的字符串needle需要匹配的字符串 作用在 haystack 指向的字符串中查找 needle 指向的字符串也是首次匹配
返回值
找到了找到的字符串的首地址没找到返回 NULL
示例
void fun13()
{char *str abcddefcde;char *p strstr(str,cde);printf(%ld\n,p - str); //7
}11. atoi/atol/atof 字符串转数字
语法 int atoi(const char *nptr);
long atol(const char *nptr);
double atof(const char *nptr);参数 nptr被转的字符串 作用将 nptr 指向的字符串转换成整数、长整形、浮点型(小数默认是double)
void fun14()
{int num01 atoi(123);printf(%d\n,num011); //124long num02 atol(1111111);printf(%ld\n,num021); //1111112double f03 atof(1.23);printf(%.2lf\n,f031); //2.23
}12. strtok 字符串切割
语法 char *strtok(char *str, const char *delim);参数 str被切割的字符串delim切割的字符串 返回值 切割出的字符串首地址切割失败返回NULL 作用字符串切割按照 delim 指向的字符串中的字符切割 str 指向的字符串。
其实就是在 str 指向的字符串中发现了 delim 字符串中的字符就将其变成’\0’调用一次 strtok 只切割一次切割一次之后再去切割的时候 strtok 的第一个参数传 NULL意思是接着上次切割的位置继续切 。
注意 如果 str 字符串中出现了连续的几个 delim 中的字符则只将第一个字符变成’\0’ 示例1
void fun15()
{char s[] 123,,,...456##..789,,..;char *str s;char *delim ,.#;char *p strtok(str,delim);printf(%s\n,p); //123char *p1 strtok(NULL,delim);printf(%s\n,p1); //456char *p2 strtok(NULL,delim);printf(%s\n,p2); //789char *p3 strtok(NULL,delim);printf(%p\n,p3); //(nil)
}示例2优化重复代码并将切割出来的字符串写入数组
void fun16()
{char s[] 123,,,...456##..789,,..;char *str s;char *d ,.#;char *buf[3];char *p strtok(str, d);int i 0;while(1){buf[i] p;i;p strtok(NULL, d);if (p NULL){break;}}for (int j 0; j 3; j){printf(buf[%d]%s\n, j, buf[j]);}
}
// buf[0]123
// buf[1]456
// buf[2]789示例3再优化
void fun17()
{char s[] 123,,,...456##..789,,..;char *d ,.#;char *buf[3] {s, NULL};int i 0;while((buf[i] strtok(buf[i], d)) ! NULL (i));for (int j 0; j 3; j){printf(buf[%d]%s\n, j, buf[j]);}
}
// buf[0]123
// buf[1]456
// buf[2]7892. 组包
13. sprintf格式化输出
语法 int sprintf(char *buf, const char *format, … );参数 buf输出到指定的内存首地址format输出的格式值输出的内容 作用将 值 按照 format 格式 输出到 指定的 buf内存中
示例
void fun18()
{char *str[100];sprintf(str, %d年%d月%d日\n, 2023, 11, 06);printf(str%s\n, str); //str2023年11月6日
}扩展使用如下
13.1 数字转字符串
void fun19()
{char *str[100];sprintf(str, %d, 2023);printf(str%s\n, str); //str2023
}13.2 字符串拼接
void fun20()
{//字符串拼接char *str01 hello;char *str02 world;char str[100];sprintf(str,%s%s,str01,str02);printf(%s\n,str); //helloworld
}3. 解包
14. sscanf格式化输入
语法 int sscanf(const char *buf,const char *format, … );参数 buf从指定的内存首地址读入信息format输入的格式值输入的内容 作用将 值 按照 format 格式 从 buf 指定的内存区域中读入信息
示例
void fun21()
{char *str 2023年11月6日 20:33:58;int y 0;int m 0;int d 0;int h 0;int min 0;int s 0;sscanf(str,%d年%d月%d日 %d:%d:%d,y,m,d,h,min,s);printf(y%d\n,y);printf(m%d\n,m);printf(d%d\n,d);printf(h%d\n,h);printf(min%d\n,min);printf(s%d\n,s);
}
// y2023
// m11
// d6
// h20
// min33
// s5814.1 读指定宽度的数据%[width]s
格式化 占位符 前面可以加宽度%2d一般用于数字
%s 前面一般不会加宽度。
void fun22()
{char *str 1234567890;int num 0;char c 0;char s[3];sscanf(str, %2d%c%s, num, c, s);printf(num%d\n, num); //12printf(c%c\n, c); //3printf(s%s\n, s); //4567890 因为取得是首地址所以会拿到4没有遇到\0,所以会直接取到结束printf(s%c\n, *s); //4
}14.2 跳过数据 %*s 或 %*d
void fun23()
{//跳过前两个数据再取两个地址char *str 1234567890;int num 0;sscanf(str, %*2d%2d, num);printf(num%d\n, num); //num34
}14.3 %[a-z] 表示匹配 a 到 z 中任意字符(贪婪性:尽可能多的匹配)
void fun24()
{//char *str acdeAZ123abcd;char p[100];sscanf(str, %[a-z], p);printf(%s\n, p); //acde
}14.4 %[aBc] 匹配aBc中一员,贪婪性
void fun26()
{char *str aaaBccBaedf;char p[100];sscanf(str,%[aBc],p);printf(%s\n,p); //aaaBccBa
}14.5 %[^aFc] 匹配非 aFc 的任意字符,贪婪性
void fun27()
{char *str dsssaFcvrdf;char p[100];sscanf(str,%[^aFc],p);printf(%s\n,p); //dsss
}14.6 %[^a-z]表示读取除 a-z 以外的所有字符
void fun25()
{char *str abcdedfA123abc;char p1[100];char p2[100];sscanf(str,%[^a-z],p1);printf(%s\n,p1); //结果啥也没有所以得先跳过前面的小写sscanf(str,%*[a-z]%[^a-z],p2);printf(%s\n,p2); //A123
}14.7 练习
使用 sscanf 两个#号之间的字符串 abc#defghi
void fun28()
{char buf[20];sscanf(abc#defghi,%*[^#]%*c%[^],buf);printf(%s\n,buf); //def
}