1. 字符串概念以及基本操作(概念,定义,调用)
字符串是以0或者'\0'结尾的字符数组,(数字0和字符'\0'等价),字符数组只能初始化5个字符,当输出的时候,从开始位置直到找到0结束
字符数组部分初始化,剩余填0
如果以字符串初始化,那么编译器默认会在字符串尾部添加'\0'
说明:
sizeof计算数组大小,数组包含'\0'字符
strlen计算字符串的长度,到'\0'结束
示例代码:
//字符串基本操作 //字符串是以0或者'\0'结尾的字符数组,(数字0和字符'\0'等价) void test01(){ //字符数组只能初始化5个字符,当输出的时候,从开始位置直到找到0结束 char str1[] = { 'h', 'e', 'l', 'l', 'o' };出现乱码!因为找不到\0 printf("%s\n",str1); //字符数组部分初始化,剩余填0 char str2[100] = { 'h', 'e', 'l', 'l', 'o' };不会出现乱码,因为其余位置自动补0 printf("%s\n", str2); //如果以字符串初始化,那么编译器默认会在字符串尾部添加'\0' char str3[] = "hello";自带\0 printf("%s\n",str3); printf("sizeof str:%d\n",sizeof(str3));6 printf("strlen str:%d\n",strlen(str3));5 //sizeof计算数组大小,数组包含'\0'字符 //strlen计算字符串的长度,到'\0'结束 //那么如果我这么写,结果是多少呢? char str4[100] = "hello"; printf("sizeof str:%d\n", sizeof(str4));100 printf("strlen str:%d\n", strlen(str4));5 //请问下面输入结果是多少?sizeof结果是多少?strlen结果是多少? char str5[] = "hello\0world"; printf("%s\n",str5);hello printf("sizeof str5:%d\n",sizeof(str5));12 printf("strlen str5:%d\n",strlen(str5));5 //再请问下面输入结果是多少?sizeof结果是多少?strlen结果是多少? char str6[] = "hello\012world";\012算一个 printf("%s\n", str6);hello 换行 world printf("sizeof str6:%d\n", sizeof(str6));12 printf("strlen str6:%d\n", strlen(str6));11 } |
八进制和十六进制转义字符:
在C中有两种特殊的字符,八进制转义字符和十六进制转义字符,八进制字符的一般形式是'\ddd',d是0-7的数字。十六进制字符的一般形式是'\xhh',h是0-9或A-F内的一个。八进制字符和十六进制字符表示的是字符的ASCII码对应的数值。转为10进制对于ascll表字符 比如 :
|
2.字符串拷贝功能实现操作
前提都要先初始化一下,不要是野指针 //拷贝方法1---利用数组下标拷贝(其实也是指针)函数内的数组下标相当于*(p+i) void copy_string01(char* dest, char* source ){//将内存一个个取出来,放入另一个,到结束符为止 for (int i = 0; source[i] != '\0';i++){ dest[i] = source[i]; } } //拷贝方法2---利用指针进行拷贝 void copy_string02(char* dest, char* source){ while (*source != '\0' /* *source != 0 */){遍历一整个字符串,俩个首地址一个个按步长增加,然后赋值 *dest = *source; source++; dest++; } } //拷贝方法3(较难) void copy_string03(char* dest, char* source){ //判断*dest是否为0,0则退出循环 while (*dest++ = *source++){} } |
3. 字符串反转模型操作
方法1:利用下标的方法 void reverse_string(char* str){ if (str == NULL){ return; } int begin = 0; int end = strlen(str) - 1; while (begin < end){判断当头坐标大于尾坐标时,不能相等,因为偶数永远不会相等 //交换两个字符元素 char temp = str[begin]; str[begin] = str[end]; str[end] = temp; begin++; end--; } } void test(){ char str[] = "abcdefghijklmn"; printf("str:%s\n", str); reverse_string(str); printf("str:%s\n", str); } |
方法2:利用字符串指针
4.字符串的格式化
4.1sprintf打印到字符串
#include <stdio.h> int sprintf(char *str, const char *format, ...); 功能: 根据参数format字符串来转换并格式化数据,然后将结果输出到str指定的空间中,直到出现字符串结束符 '\0' 为止。 参数: str:放入的字符串首地址,格式化后往地址内填充字符数据类型要是开辟好的char形 format:字符串格式,用法和printf()一样 ...:格式化中的参数(可多位) 返回值: 成功:实际格式化的字符个数(strlen的结果) 失败: - 1 |
sprintf格式化类型:
void test(){ //1. 格式化字符串(常用) 最好不能是空指针或者是野指针 char buf[1024] = { 0 }; sprintf(buf, "你好,%s,欢迎加入我们!", "John"); printf("buf:%s\n",buf); memset(buf, 0, 1024); sprintf(buf, "我今年%d岁了!", 20); printf("buf:%s\n", buf); //2. 拼接字符串 memset(buf, 0, 1024); char str1[] = "hello"; char str2[] = "world"; int len = sprintf(buf,"%s %s",str1,str2); printf("buf:%s len:%d\n", buf,len); //3. 数字转字符串格式化输出 memset(buf, 0, 1024); int num = 100; sprintf(buf, "%d", num); printf("buf:%s\n", buf); //设置宽度 右对齐 memset(buf, 0, 1024); sprintf(buf, "%8d", num);一共宽度是8,右对齐 printf("buf:%s\n", buf); //设置宽度 左对齐 memset(buf, 0, 1024); sprintf(buf, "%-8d", num); printf("buf:%s\n", buf); //转成16进制字符串 小写 memset(buf, 0, 1024); sprintf(buf, "0x%x", num); printf("buf:%s\n", buf); //转成8进制字符串 memset(buf, 0, 1024); sprintf(buf, "0%o", num); printf("buf:%s\n", buf); } |
4.2 sscanf筛选解析字符串
#include <stdio.h> int sscanf(const char *str, const char *format, ...); 功能: 从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据。 参数: str:指定的字符串首地址 format:字符串格式化,用法和scanf()一样 ....:放入的字符首地址 返回值: 成功:成功则返回参数数目,失败则返回-1 失败: - 1 |
format具体格式:%d也是%s的一种,在这里数字也是一种特殊字符
格式 | 作用 |
%*s或%*d | 跳过数据 |
%[width]s | 读指定宽度的数据 |
%[a-z] | 匹配a到z中任意字符(尽可能多的匹配) |
%[aBc] | 匹配a、B、c中一员,贪婪性 |
%[^a] | 匹配非a的任意字符,贪婪性 |
%[^a-z] | 表示读取除a-z以外的所有字符 |
sscanf类型:
匹配机制:从头开始对应匹配机制(%*d%s)按段落匹配
//匹配第一个字符是否是数字,如果是,则跳过
//如果不是则停止匹配
如果匹配失败直接停止匹配
匹配成功则跳过或者打印。
//1. 跳过数据(bug太多,适用于前半段都是错误的情况) void test01(){ char buf[1024] = { 0 }; //跳过前面的数字 //匹配第一个字符是否是数字,如果是,则跳过 //如果不是则停止匹配 sscanf("123456aaaa", "%*d%s", buf); printf("buf:%s\n",buf); } //2. 读取指定宽度数据(要几个写几个) void test02(){ char buf[1024] = { 0 }; //跳过前面的数字 sscanf("123456aaaa", "%7s", buf); printf("buf:%s\n", buf); } //3. 匹配a-z中任意字符 void test03(){ char buf[1024] = { 0 }; //跳过前面的数字 //先匹配第一个字符,判断字符是否是a-z中的字符,如果是匹配 //如果不是停止匹配 sscanf("abcdefg123456", "%[a-z]", buf); printf("buf:%s\n", buf); } //4. 匹配aBc中的任何一个 void test04(){ char buf[1024] = { 0 }; //跳过前面的数字 //先匹配第一个字符是否是aBc中的一个,如果是,则匹配,如果不是则停止匹配 sscanf("abcdefg123456", "%[aBc]", buf); printf("buf:%s\n", buf); } //5. 匹配非a的任意字符(常用!!!) void test05(){ char buf[1024] = { 0 }; sscanf("bcdefag123456", "%[^a]", buf); printf("buf:%s\n", buf); } //6. 匹配非a-z中的任意字符 void test06(){ char buf[1024] = { 0 }; sscanf("123456ABCDbcdefag", "%[^a-z]", buf); printf("buf:%s\n", buf); } |
课堂小练习:
1.实现ip地址4段分别4个变量接收(注意,接收端一定要是首地址!).分段匹配
2.已给定字符串为:123abcd$myname@000qwe.请编码实现匹配出myname字符串,并输出.(要利用失败停止匹配的原则)
3.已给定字符串为: helloworld@itcast.cn,请编码实现helloworld输出和itcast.cn输出。
5.字符串查找操作
算法思路:
先遍历总数据指针里的数据,一个个遍历,当遍历到总数据指针和查找指针数据相同的时候
分别创建俩个临时指针,分别同时向后遍历看看后续是否一样,不一样退出让总数据大指针接着后移,进行原来的遍历操作。
当后续全部相等,查找指针完成遍历到达最后一个\0,成功返回位数。
#include <stdio.h>
int my1(char *str,char *substr)
{
int num=0;
while(*str!='\0')//遍历总指针
{
if(*str!=*substr) //当总指针和查找指针一样时
{
str++;//总指针跳下一个地址
num++;
continue;
}
//创建俩个临时指针
char *tmpStr = str;
char *tmpsubStr = substr;
while(*tmpsubStr !='\0')
{
if(*tmpStr!= *tmpsubStr) //匹配失败情况
{
str++;
num++;
break;
}
tmpStr++;
tmpsubStr++;
}
if(*tmpsubStr=='\0')//匹配成功情况
{
return num;
}
}
return -1;
}
void main()
{
char *str ="abcdefgaa";
int ret =my1(str,"def");
if(ret!= -1)
{
printf("找到位置在%d\n",ret);
}
else
{
printf("11111111111111");
}
}