字符数组

定义:元素是字符的数组,是字符数组。例如:char a[5];

字符数组及其函数操作


/*
p_chararray_1.cpp 
字符数组处理字符串 v1.2.7 2025-6-29
---------------------------------------------------
输入:scanf
输出:printf
带空格输入:fgets 
长度:strlen
拼接:strcat
复制:strcpy
比较:strcmp
---------------------------------------------------
部分拼接:strncat
部分复制:strncpy
忽略大小写比较:stricmp
部分比较:strncmp
小写变大写:strupr
大写变小写:strlwr
查找字符:strchr 
查找字符串: strstr
数组与指针:
分割:csplit 
---------------------------------------------------
windows     linux 
---------------------------------------------------
gets        fgets 
stricmp     strcasecmp
---------------------------------------------------
*/
#include <iostream> // 万能库 #include <bits/stdc++.h>
#include <cstring>  //strlen等C函数 
using namespace std;

//src 源数组,字符串数字,空格分开,例如:12 65 73 86 97 
//dst 返回数组,int类型元素,       例如:12 65 73 86 97 
void csplit(char src[],int dst[]) {
	char *p;
	p=strtok(src," "); //空格
	int i=0;           //dst数组下标 
	while (p!=NULL) {
		dst[i++]=atoi(p);
		p=strtok(NULL," ");
	}
}

int mystricmp(char a[],char b[]) { //自定义函数:忽略大小写字符的比较
	//1 a>b
	//==0 a==b
	//-1 a<b
	int len=strlen(a);
	for (int i=0;i<len;i++) {
		char x,y;
		x=a[i];
		if (x>='A' && x<='Z') {
			x+=32; //大写变小写
		}
		y=b[i];
		if (y>='A' && y<='Z') {
			y+=32; //大写变小写
		}
		if (x==y) {
			;      //空操作
	    }
	    else if (x>y) {
			return 1;
		}
		else {
			return -1;
		}
	}
	return 0;
}

void mystrlwr(char a[]) { //数组名a,a是数组的地址
	//转换为小写
	int len=strlen(a);
	for (int i=0;i<len;i++) {
		char x;
		x=a[i];
		if (x>='A' && x<='Z') {
			x+=32;
			a[i]=x;
		}
	}
}

void mystrupr(char a[]) { //数组名a,a是数组的地址
	//转换为大写
	int len=strlen(a);
	for (int i=0;i<len;i++) {
		char x;
		x=a[i];
		if (x>='a' && x<='z') {
			x-=32;
			a[i]=x;
		}
	}
}

int main() {
	/*//存储字符 
	char a[3];
	a[0]='A';
	a[1]='B';
	cout<<a;
	if (a[2]=='\0') cout<<"结束符\n";*/
	
	/*//存储字符串,末尾自动加结束符'\0' 
	char a[5]="AB";
	if (a[2]=='\0') cout<<"结束符\n"; 
	cout<<a<<endl;
	if (a[3]=='\0') cout<<"a[3]也是\0";*/
	
	/*//输入字符串,cin会忽略空格、换行 
	char a[20];
	cin>>a;   
	cout<<a;*/
	
	/*//scanf读字符串,忽略空格 
	char a[20];
	scanf("%s",a);    //%s string scan format 
	printf("%s\n",a); // */
//    puts(a);          //输出并换行,等价上一行
	
	/*//输入字符串,倒序输出字符
	char a[10];
	scanf("%s",a);
	int len=strlen(a);       //求字符串长度
	for (int i=len-1;i>=0;i--)
	{
		printf("%c",a[i]);   
	}*/
				
	/*//算大小:内存大小;字符串长度 
	char a[]="China";
	//a="China";     //不能这样写 
	cout<<"内存大小:"<<sizeof(a)<<endl; //6字节,后面自动加'\0' 
	cout<<"字符串长度:"<<strlen(a);      //字符个数:5 */
	 
    //全部读字符串,含空格 
    const int N=20;
	char a[N];           //输入:Hello world 
    fgets(a,N+1,stdin);   
    printf("%s",a);      //Hello world

    /*//换行有3种方法
	printf("\n"); 
    puts("");
	cout<<endl;*/

    /*//逐字符赋值,最后会自动加字符串结束标志 
    char c[10]={'H','e','l','l','o','x'}; //没有结束符 '\0'
      //下标:   0   1   2   3   4   5   6 
    cout<<strlen(c)<<endl;                //6个字符 
    for (int i=0;i<10;i++) {
		if (c[i]=='\0') {                  //遇到'\0'就跳出
			cout<<"遇到\\0跳出,此时i="<<i; //第6个位置,从0开始计数 
			break;
		}
	} */

    /*//判断字符串结束的第二种方法 
    char a[10]="Hello";
    int i;
	for (i=0;a[i];i++) { 
	                       //a[i]是字符,按它的ascii码作为条件
						   //'\0'的ascii码恰好为0,就退出循环 
         ;                 //空语句 
		 cout<<a[i]; 
	}
	printf("\n遇到结束符,此时i=%d",i); //遇到结束符,此时i=5 */

    /*//字符串拼接 
	char str1[]="Hello";
	char str2[]="World";
	strcat(str1,str2); //str2连接在str1后,返回str1
	printf("%s",str1); //HelloWorld */
	
	/*//部分字符串拼接  cat,catenate 连接 
	char str1[100]="Hello";
	char str2[]="World";
	strncat(str1,str2,3); //str2的前3个连接在str1后
	printf("%s",str1);    //HelloWor */ 
 
    //字符串复制 cpy copy的缩写 ;str 就是string的缩写 
    /*char str1[100];
	char str2[]="HelloWorld";
	strcpy(str1,str2); //复制str2到str1,返回str1
    //str1=str2;       //不能这样写 
	printf(str1); */

    //字符串部分复制  cpy,copy 复制 
    /*char str1[10]="";
	char str2[]="hello"; 
	strncpy(str1,str2,3); //复制str2的前3个字符到str1,返回str1
	printf(str1);         //Hel
	printf("\n%lld",strlen(str1)); //3 lld,表示输出长整数 ll: long long*/
	
	/*//比较大小 string compare
	char str1[10]="Werld";
	char str2[10]="World";
	int t=strcmp(str1,str2);
	if (t>0) {
		printf("%s > %s",str1,str2);
	}
	else if (t==0) {
		printf("%s = %s",str1,str2);
	}
	else if (t<0) {
		printf("%s < %s",str1,str2);
	} */

    //比较忽略大小写的字符串 i stricmp不能用,自己做一个
    /*char str1[10]="hello";
	char str2[10]="HELLO";
	int t=stricmp(str1,str2); //i: ignore 忽视  string ignore compare
	                          //                str    i      cmp 
	if (t>0) {
		printf("%s > %s",str1,str2);
	}
	else if (t==0) {
		printf("%s = %s",str1,str2);
	}
	else if (t<0) {
		printf("%s < %s",str1,str2);
	}*/

    //部分比较 strncmp
	/*char str1[10]="Hello";
	char str2[10]="Helmnaf";
	int t=strncmp(str1,str2,3); //取str1的前3个、str2的前3个比较
	if (t>0) {
		printf("%s > %s",str1,str2);
	}
	else if (t==0) {
		printf("%s = %s",str1,str2);
	}
	else if (t<0) {
		printf("%s < %s",str1,str2);
	}*/

    //大写变小写, strlwr不能用,自己编一个
	/*char a[10]="HeLLo"; //有3个大写字母
	mystrlwr(str);          //lwr,lower 较小的 
	printf("%s",str);     //hello */
	
	//小写变大写,strupr不能用,自己编一个mystrupr
	/*char a[10]="HeLLo"; //有2个小写字母
	mystrupr(a);          //upr,upper 上面的 
	printf("%s",str);     //HELLO*/
	
	//找字符 strchr: chr 就是char , str 是 string的缩写 
	/*char a[20]="HelloWorld"; 
	char *p;                //p是指向char类型的指针 
	p=strchr(a,'W');   	    //p是指向W的指针 
	printf("原始值:%s\n",a);
	printf("地址:%p\n",p); //地址 
	cout<<"值:"<<*p;       //W 
	cout<<endl; 
	cout<<p;               //World
    cout<<endl;    
    cout<<*p++;            //W,*优先级高于++          
    cout<<endl;
    cout<<*p;              //o             
    p++; 
    cout<<endl;
    cout<<*p;              //r*/


    //找子串位置:strstr,str是string的缩写 
	/*char a[20]="HelloMyWorld";
	char *p;
	p=strstr(a,"My");     //p指向 M 
	cout<<*p;             //M */

    //测试找不到时的空指针 
    /*char a[20]="HelloMyWorld";
    char *p;
    p=strstr(a,"Car"); //没找到,返回NULL 
	if (p==NULL) cout<<"p=NULL"<<endl;           //传统C语言 
	if (p==nullptr) cout<<"in c++ 11,p=nullptr"; //编译 -std=c++11*/
    
	//用指针访问元素: MyWorld
	/*char a[20]="HelloMyWorld";
    char *p;          //指针就是地址 
    p=strstr(a,"My"); //p指向 M 
	while (p!=nullptr && *p!='\0') {
		cout<<*p;
		p++;          //指针往后移动一个位置 
	} */

	//数组下标访问数组元素 
	/*char a[20]="HelloMyWorld";
	int i=0; 
	while (a[i]!='\0') {
		printf("地址:%p 值:%c\n",&a[i],a[i]); //地址:000000000070fe01 值:e
		                                        //16个十六进制数,占64位 
		i++;
	}*/

    //数组名做指针运算 
	/*char a[20]="HelloMyWorld";
	int i=0; 
	while (*(a+i)!='\0') {
		printf("地址:%p 值:%c\n",a+i,*(a+i)); 
		i++;
	}*/

	//字符指针访问数组元素 
	/*char a[20]="HelloWorld";
    char *p=a;              //字符指针指向数组a 
    printf("内存地址	 值\n"); 
	while (p!=nullptr && *p!='\0') {
		printf("%p %c\n",p,*p); 
		p++;
	} 
	char *q;                //字符指针指向字符 
	q=strchr(a,'W'); 
	printf("原始值:%s\n",a);
	printf("地址:%p\n",q); //地址 
	cout<<"值:"<<*q;       //W */

	//结论:如果 char a[20]="Hello"; char *p=a; 
	//a[i]  = *(a+i)  = *p
	//&a[i] = a+i     = p+i
	
	//思考:如果把char换成int,看地址如何变化? 

    //用指针访问前面的3个元素,要求按顺序写出,练习写出
    /*char sname[20]="HeABoMyWorld";
    char *p;
    p=strstr(sname,"My"); //p指向 M
	int n=3;              //控制循环3次 
	for (int i=0;i<n;i++) p--;      //左移3步
	for (int i=0;i<n;i++) cout<<*p++;*/


    //字符指针s保存字符串,也可用查找
	/*char *s="HelloMyWorld";
	cout<<*s<<endl;
	char *p;
	p=strstr(s,"My");   //p指向 M 
	cout<<*p<<endl;
    int len=strlen(s);  //字符指针,可看做数组名
	for (int i=0;i<len;i++) {
		cout<<s[i]<<' ';
	}
    cout<<endl;
    while (s!=nullptr && *s != '\0') { //指针打印
    	cout<<*s<<' ';
    	s++;                           //指针指向后面字符 
	} */
    
    //字符串转数字
	/*char s[20]="1234";
	int x=atoi(s);
	x++;
	cout<<x<<endl; //1235*/

    //数字转字符数字,自编程序
    //int x=1234;
	
	//字符串转小数 
	/*char s[20]="1234.56";
	double x=atof(s);
	cout<<x<<endl; //1234.56*/

    //判断字符是不是字母 
    /*char c='%';
    if (isalpha(c)) //c>='a' && c<='z'麻烦
		cout<<c<<"是字母";
	else
		cout<<c<<"不是字母";*/

    //整数进制转换,自编
    /*char s[20];
    itoa(0b100111,s,10); //参数1: 原始数字 0b开头,表示是二进制数字 
	               		//参数2:数组 
	               		//参数3: 进制数 16表示十六进制 
    cout<<s<<endl;*/
  
    //分割字符串,包装成函数csplit更好用
//	This
//	a
//	sample
//	string
//	OK 
	/*char s[]="- This, a sample string, OK.";
	char *p;            //指向字符类型的指针 
	p=strtok(s," ,.-"); //空格 , . - 四种分割字符
	while (p!=NULL) {
		cout<<p<<endl;
		p=strtok(NULL," ,.-");
	} */

    //把格式化字符串数字分割,存入数组,相当于python的split 用途:读取输入数据 
    /*char s[]="12 65 73 86 97"; //数字字符串,空格分开 
	char *p;
	p=strtok(s," "); //空格
	int a[10];
	int i=0;         //a数组下标 
	while (p!=NULL) {
		a[i++]=atoi(p);
		p=strtok(NULL," ");
	}
	for (int j=0;j<i;j++) { //打印a数组数字
		cout<<a[j]<<' ';
	}*/ 
    
	//自做的分割字符串数字函数csplit,要求提前分配容量 
    /*const int N=5;
    char s[]="12 65 73 86 97";
	int t[N]={0}; 
    csplit(s,t);
    for (int i=0;i<N;i++) cout<<t[i]<<' ';*/


    //普通字符串,空格分开
    /*char s[]="Ab xyz    ccD    Mn   8p";  
	char *p;
	p=strtok(s," "); //空格
	while (p!=NULL) {
		cout<<p<<endl; 
		p=strtok(NULL," ");
	}*/

    //二维数组,看做一维数组,每个元素又是一维数组 
	/*char a[3][5] = {   "abc",
	                   "mno",
					   "xyzv"};
	for (int i=0;i<3;i++) {
		puts(a[i]);          		//a[i]是一维数组,有5个元素 
		printf("%p\n",a[i]);        //a[i]相当于数组名,就是地址 
	}*/
		
	return 0;
}