C++ 字符数组所有知识点 指针

不讲string 只讲char 数组名[ ]   和   const char * 数组名,以及二维数组

所以这篇,所有变量声明都是char 带一个方括号[ ]类型!但是最近看了B站某个培训班课程,老师将以‘ 0’ 结尾的叫字符串,不以‘ 0 ’ 结尾的叫字符数组!

char strA[]{'s','k','i','r','t'};
	
	char strB[]{'s','k','i','r','t','\0'};

strA是字符数组,strB是字符串!这样可能更专业但是本文中,我不采用这种叫法。。 

1.  声明和初始化格式:

char mess[]{'A','B','C'};
cout<<mess<<endl;
char mess2[] {'h','l','e','w'};
cout<<mess2<<endl;

但是,在打印这两个字符数组的时候就开始出现奇怪的现象了。垃圾信息出现!

解决办法1:结尾的‘\0’  补上,变成标准的C字符数组。

char mess[]{'A','B','C','\0'};
cout<<mess<<endl;
char mess2[] {'h','l','e','w','\0'};
cout<<mess2<<endl;

解决办法2:不写 '\0' 了,正确写好整个数组长度,记得给null字符也占用一个位置。例如下图,有6个字母,一定要写7.千万别写6!

char mess3[7] {'f','o','o','t','b','a'};
cout<<mess3<<endl;

解决办法3:字面量的C字符串。

char mess4[] {"watch"};
cout<<mess4<<endl;

多个单词也行:

char mess5[] {"outside the sky"};
cout <<mess5<<endl;

出错案例展示:来自B站课程5_哔哩哔哩_bilibili   1小时42分

char str[10]={0};
for(size_t i=0;i<10;i++){
	scanf("%c",&str[i]);
}//helloworld  一共10个字母
printf("shuchu\n");
	printf("%s\n",str);//多了个叹号 !老师的演示是多了一堆乱码
for(size_t i=0;i<10;i++){
	printf("%c \n",str[i]);
} 
//用for循环一个个打印倒是又没错了
//所以一定要写的比方括号里的数字短一个字符!

2.  二维C++ 字符数组

char words[][10] {
		{'f','o','o','t'},
		{'w','o','r','s','e'},
		{'a','r','o','m','a'}
	};
	size_t wordslen=sizeof(words)/sizeof(words[0]);
	
	//cout<<wordslen; 
	//3 这是一个3行 10列的数组  不够10的都自动填充'\0'
	 
	//遍历方法 一个一个字母输出 不要直接cout<<words[i] 
	for(size_t i{0};i<wordslen;i++){
		for(size_t j {0};j<10;j++){
			cout <<words[i][j]<<"   ";
		}
		cout<<endl;
	}
	

C语言形式的二维字符数组 。遍历方法也略有不同

	char members[][10] {
		"Samuels",
		"David",
		"Felly",
		"Dolly"
	};
	size_t memlen=sizeof(members)/sizeof(members[0]);
//	cout<<memlen<<endl;    //4
	for(size_t i{0};i<memlen;i++){
		cout<<members[i]<<endl;
	}

另外补充代码习惯问题,这样写可以减少变量的数目。

//不良代码写法  
	
	char advice1[] {"hello, foreigner"};
	char advice2[] {"I've seen a car"}; 
	//也能正常打印
	
	//更好的做法
	char advices[][50]{
		"hello, foreigner",
		"I've seen a car",
		"The fox is yellow"
	} ;
	cout<<advices[2]<<endl;

3.头文件 cctype   ,函数isdigit, isnum, isalpha, isblank等等

cout<<"---#include <cctype>---"<<endl;
	char ch1 {'A'};
	cout<<isalnum(ch1)<<endl;
	cout<<isalpha(ch1)<<endl;
	
	
	//大小写转换
	char sentance [] {"There is a white fox"};
	size_t word_num=sizeof(sentance )/sizeof(sentance [0]);
	char sentan2 [word_num];
	for(size_t i=0;i<word_num;i++){
		sentan2[i]= toupper(sentance [i]) ; 
	} 
	cout<<sentan2<<endl;
	cout<<sentance <<endl; 

例1:找出句子中一共有多少个空格

//find the blank
	char mess1[] {"Hello friend, what is your name"};
    int blankcount {};
    size_t all=sizeof(mess1)/sizeof(mess1[0]);
	for(size_t i=0;i<all;i++){
		if(isblank(mess1[i])){
			cout<<"Find a Blank"<<endl;
			blankcount++;
		}
	}
	cout<<blankcount<<endl;

 例2:找出句子中有多少个数字

//find digits
	char statements [] {"The aboretum has 128 kinds of plants.15 kinds are very rare"};
	
	for(auto ch : statements ){
		if(isdigit(ch)){
			cout<<"Find a num   "<<ch<<"   ";
		}
	}

4.头文件cstring--strcmp比较,strcat拼接(改变原有),  strcpy复制, 

4.1 strlen( 字符数组名)

cout<<"---#include <cstring>---"<<endl;
	cout<<"---strlen---"<<endl;
	cout<<strlen(sentance )<<endl;

4.2 strcmp, strncmp 将两个字符串进行比较,按照字母表排序

cout<<"---strcmp--结果 -1 0 +1-----"<<endl;
		//char *book1 {"The heaven bird"};   警告
		const char *book1 {"The blue bird"} ;
		const char *book2 {"The hydarte earth"} ;
		cout<<strcmp(book1,book2)<<endl;  


	cout<<"---strncmp--第三个参数表示比较几个字符-----"<<endl;
	cout<<strncmp(book1,book2,3)<<endl;

4.3 strchr,strrchr 在字符串中寻找单个字符,并从匹配的地方进行截取。

例:从book1  the blue bird中寻找字符 ' u' ,找到了,那么返回以u为首的剩下的字符串。

cout<<"---strchr--从相同的地方开始-----"<<endl;
	cout<<strchr(book1,'u')<<endl;	//ue bird
	cout<<*strchr(book1,'u')<<endl;  //u
	//老师的例子
		const char *mess5 {"Try to do The sucess is noT far."} ;
		const char *result =mess5;
		char Target {'T'};
		int pos {};
    	while((result=strchr(result,Target))!=nullptr){
    		cout<<"找到了 "<<Target<<"  "<<result<<endl;
			result++;
			pos++;
		}
		cout<<pos<<endl;

	cout<<"---strrchr--从末尾开始往前找-----"<<endl;
    
    //Juti具体应用:截断文件的扩展名 
    char input[]{"D:/devC++ Progect/myt.txt"};
    char *res=strrchr(input,'.');
    if(res!=nullptr){
		 cout<<res+1<<endl;//把找到的点跳过去 
	}
	else{
		cout<<"没找到了"<<endl; 
	}

4.4 strcat, strncat 将两个字符串拼接

cout<<"---strcat-----"<<endl;
 char dest[40]="hello   ";
 char behind[40]="world";
strcat(dest,behind);
cout<<dest<<endl;


 cout<<"---strncat-----"<<endl;

 char ff[40]="Meeting you   ";
 char bb[40]="are nice very much";
 strncat(ff,bb,8);
 cout<<ff<<endl;
  cout<<"---strcat注意事项-----"<<endl;
 char *str1=new char [10] {'A','B','C','D','\0'};
 cout<<strlen(str1)<<endl;
 char *str2=new char [10] {'!','W','Q',' ','F','r','\0'};
  cout<<strlen(str2)<<endl;
 strcat(str1,str2);
 cout<<"合并后长度"<<strlen(str1)<<endl;

4.5 strcpy( 前者,后者) ,将后者拷贝到前者中。 strncpy

 
 cout<<"---strcpy(dest,source)  记住前者被后者覆盖了-----"<<endl;
 char source[10]="Meeting Y";
 char *dest3=new char [11];
 strcpy(dest3,source);
 cout<<dest3<<endl;
 
 
 cout<<"---strncpy(dest,source,n)  -----"<<endl;
 const char *sour2="Cookbiscuit";
 char dest4[] {'H','E','L','L','P','\0'};
 strncpy(dest4,sour2,4);//dest4的前4个字符被 资源库的4个字符覆盖 
 cout<<dest4<<endl;//CookP

4.6补充,C语言 strstr (strA, tarstrB) 

头文件<string.h>

在字符串strA中,寻找目标子串tarstrB,如果找不到,返回NULL,如果找到了,返回匹配子串为首的剩余字符串。

//字符串查找 找到的次数  利用已有的strstr   <string.h> 
int ser_time(char *sear,char*tar){
	int k=strlen(tar);
    int count=0;
    char *r=strstr(sear,tar);

	while(r!=nullptr){
		printf("%s\n",r);
		r+=k;
		count++;
	    r=strstr(r,tar);//再新的  掐去了头的 字符串里寻找 
	}
	return count;
}

4.7 补充,C语言 strtok(strA, line)   <string.h>

 

按照既定的分隔符line ,来拆分字符串strA。语法

char* strtok( char* str, const char* delim)

 返回值:拆分后的首地址。

 char strG[]="www.baidu.com.cn";
   char *ret3=strtok(strG,".");
	printf("%s\n",ret3);

原来的strG变成了www\0 baidu.com,www成为了一个独立的串。所以返回www的首地址。

但是strtok只能拆分一次。如果想持续拆分的话:

char strG[]="www.baidu.com.cn";
   char *ret3=strtok(strG,".");

	
	while(ret3!=NULL){
		ret3=strtok(NULL,".");
			printf("%s\n",ret3);
	}
//结果分别是
//www  baidu com  cn (null)

 注意事项:strtok的第一个参数必须可读可写,因为这个函数是在原来字符串上进行操作。以下这2种格式都是常量,不能当参数1.

char* str2="www.sina.com"

const char* str3="www.qq.com.cn" 

 4.8  C语言  <string.h>  strstr( 搜索字符串,目标字符串)

待补充

5.利用指针,记得加上const,不然编译器有警告,禁止将string变成char *

const char* car{"volve"};
char* car2 {"bwm"};//我用的red panda Dev C++就会警告

6.利用指针,二维字符数组可以写成const char*  数组名[ ],这样就不需要限定长度,变得更加灵活

	const char* benediction []{
		"We will have a happy weekend",
		"to enjoy today",
		"to be honest and brave",
		"to wear your beautiful apparus"
	};
//遍历
    for(size_t i{0};i<size(benediction);i++){
		cout<<benediction[i]<<endl;
	}

基于范围的for循环,也可以换一种遍历方式:

for(const char* dic :benediction){
 	cout<<dic<<endl;
 }

7.加了const还能修改吗?一定无法修改了吗?

const char* stuA{"Tom Cruse"};
//stuA[0]='D'; 报错了,stuA的名字是一个常量

但是修改指针指向就能改了,因为这是常量指针,不是指针常量

const char* stuA{"Tom Cruse"};
const char *stuB {"Wang wu"};

stuA=stuB;//改变指针指向
cout<<stuA<<endl;//王五,不是汤姆克鲁斯

二维指针数组类似 

 const char* students[]{
		"Tom Cruse",
		"Wang wu",
		"Zhang San",
		"Lily Ford"
	};
	//*students[0]='D';  报错,不能修改为Dom Cruse

改变指针指向,就把第一个汤姆克鲁斯变成韩明明了

	const char* stuE {"Han mingming"};
	students[0]=stuE;
	for(const char* stu:students){
		cout<<stu<<endl;
	}

注意!!如果指针常量,上文就报错了,因为指针常量的指向也是固定的,不能修改指向其他变量

 const char* const students[]{    //多了一个const在星号后面
		"Tom Cruse",
		"Wang wu",
		"Zhang San",
		"Lily Ford"
	};

8.补充,atol,  atoi,  atof

将字符串转化成长整型;long

将字符串转化成整型;int

将字符串转化成浮点型;float

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值