字符数组
概念
元素类型为char字符型的数组,字符数组往往是用来存储字符串数据的。需要注意的一点是,我们C语言中的字符是字节字符。
字节字符:也就是1个字符占1个字节,在C语言中,我们使用char表示字节。
测试题:
char a = 'A';//正确
char b = '1';//正确
char c = 65; //正确,ASCII码
char d = "A";//错误,这是字符串的写法,也是char数组的写法,char d[1] = "A"
char e = '司';//错误,中文一个字符超过1个字节
语法
char 数组名 [容量];
char 数组名 [行容量] [列容量];
字符数组的语法就是我们前面所学的一维数组和二维数组的语法,只不过数据类型是char而已。
注意:
如果我们的char数组初始化的时候,没有完全赋完值的时候,空出来的地方使用\0进行填充。
比如:char c[8] = {'h','e','l','l','o'}
等价于char c[8] = {'h','e','l','l','o','\0','\0','\0'}
字符案例
案例1:
cpp
#include <stdio.h>
//需求:字符串案例-输出一个字符串(I LOVE YOU!)
int main ()
{
//准备一个测试数组 ASCII中码0和码32对应的不是同一类的空
char arr[11] = {'I',' ','L','O','V','E',' ','Y','O','U','!'};
//通过一个for循环进行遍历输出
for(int i = 0; i < sizeof(arr) / sizeof(char);i++)
{
printf("%c",arr[i]);
}
printf("\n");
return 0;
}
案例2:
cpp
//需求:输出一个用字符组成的菱形图案
int main ()
{
//准备数据
char arr[5][5] = {
{' ',' ','*',' ',' '},
{' ','*','*','*',' '},
{'*','*','*','*','*'},
{' ','*','*','*',' '},
{' ',' ','*',' ',' '}
};
for(int i = 0; i<sizeof(arr)/sizeof(arr[0]);i++)
{
for(int j = 0;j < sizeof(arr[ i ])/sizeof(char);j++)
{
printf("%c",arr[i][j]);
}
//每一行中的列元素输出完毕,执行换行
printf("\n");
}
printf("\n");
return 0;
}
注意:
① 如果定义时不初始化,元素值不确定;
char arr1[2]; //此时属于未初始化,元素值是不确定的(随机的) char arr2[5] = {'a','b','c'}; //此时属于不完全初始化,未初始化的元素使用\0进行填充
② 如果提供的字符个数大于数组长度,则按语法错误处理;如果字符个数小于数组长度,后面的元素自动为空字符(\0)
③ 如果提供的字符个数与数组长度相同时,可省略数组长度,系统会自动确定元素个数,适合字符个数较多时。
字符串和字符串结束标志
说明
-
C语言规定,字符串以字符
\0
作为结束标志。 -
编译系统对字符串常量自动加一个
\0
作为结束标志。 -
程序中往往通过判断
\0
来检测字符串是否结束。 -
\0
的ASCII码为0,不是一个可显示的字符,是"空操作符",它什么都不做,不会增加有效字符,仅是一个工判别的标准
字符数组的多样表示
我们的char数组可以以数组的方式一个个输出每个字符;我们的char数组也可以以字符串的方式整体进行输出所有字符。
cpp
//需求:字符数组→字符串
#include <stdio.h>
int main()
{
//字符串的第一种表示:
char si[] = {'h','e','l','l','o',' ','w','o','r','l','d'};
//字符串的第二种表示:
char s2[] = {"hello world"};
//字符串的第三种表示:
char s2[] = "hello world";
//输出字符串
printf("%s,%s,%s\n",s1,s2,s3);// hello world
return 0;
}
注意:
-
字符串的长度与字符数组的长度不一定相同。
-
利用字符串常量可以对字符数组进行初始化,但不能用字符串常量为字符数组赋值。
//正确演示:利用字符串常量可以对字符数组进行初始化
char arr1[6] = "hello";
//错误演示,用字符串常量为字符数组赋值。
char arr2[6];
arr2 = "hello";
字符串的基础操作
在用格式说明符%s进行输入输出时,其输入输出项均为数组名。但在输入时,相邻两个字符串之间要用空格分隔,系统将自动的在字符串最后加结束符"\0"。在输出时,遇到结束符'\0'作为输出结束标志。
对于字符串的操作,我们需要使用到一些系统提供的函数。
字符串输入
语法:
scanf("%s",数组名);
案例:
cpp
//字符串的输入
#include <stdio.h>
int main()
{
//创建一个char数组,用来存放人的名字
char name[20];
printf("请输入您的姓名:\n");
scanf("%s",name);//如果是字符串,这里不是变量地址,是变量名,数组本身不占内存空间,数组默认指向第一个元素的首地址
printf("您的姓名是%s\n",name);
return 0;
}
注意:采用scanf()进行字符串输入,要求字符串中不能存在空格,否则字符串遇到空格会结束。
- fgets(数组名,数组容量,sdtin);
功能:
从键盘录入一个字符串到字符数组,返回字符数组的地址。
说明:采用fgets进行字符串输入,可获取所有输入的字符串,包含\n
,在实际的字符串处理时,我们可能需要处理\n
案例:
cpp
#include <string>
#include <stdio.h>
//字符串的输入
//语法:fgets(数组名,数组容量,sdtin);
int main()
{
//创建一个char数组,用来存放人的名字
char name[20];
printf("请输入您的名字:\n");
//fgets 和 scanf只能二选一
fgets (name,sizeof(name)/sizeof(char),stdin);
printf("您的姓名是:%s\n",name);
return 0;
}
注意:
① 如果输入的字符串不包括空格
和换行
,可以使用scanf() | fgets();
② 如果输入的字符串需要包含空格
和换行
,只能使用fgets();
③ 经过对比,我们发现,在字符串的输入中,fgets();
字符串输出
- printf("%s",数组名);
案例:
cpp
//字符串的输出
#include <stdio.h>
int main()
{
//创建一个char数组,用来存放人的名字
char name[20];
printf("请输入您的姓名:\n");
scanf("%s",name);//如果是字符串,这里不是变量地址,是变量名,数组本身不占内存空间,数组默认指向第一个元素的首地址
printf("您的姓名是%s\n",name);
return 0;
}
- puts(数组名)
功能:
输出一个字符串
说明:
字符串可以包含转义字符
案例:
cpp
#include <stdio.h>
//字符串的输入
//语法:fgets(数组名,数组容量,sdtin);
int main()
{
//创建一个char数组,用来存放人的名字
char name[20];
printf("请输入您的名字:\n");
//fgets 和 scanf只能二选一
fgets (name,sizeof(name)/sizeof(char),stdin);
puts(name);//无法进行拼接,只能输出
printf("您的姓名是:%s\n",name);
return 0;
}
puts(name);//无法进行拼接,只能输出
字符串拼接
- strcat(数组名(字符串1),"需要拼接的字符串(字符串2)");
引用:
#include <string.h>
案例:
cpp
#include <stdio.h>
#include <string.h>
//字符串的拼接
//语法:strcat(数组名,"需要拼接的字符串");
int main()
{
//创建一个char数组,用来存放人的名字
char name[20];
printf("请输入您的名字:\n");
//fgets 和 scanf只能二选一
fgets (name,sizeof(name)/sizeof(char),stdin);
puts(strcat(name,"快跑!"));//无法拼接,只能输出
return 0;
}
注意:
① 字符数组1(字符串1)
的长度必须足够大,以便于能容纳被连接的字符串。
② 连接后系统将自动取消字符串(字符数组)
后面的结束符'\0'
③ 字符串2
可以是字符数组名,也可以是字符串常量,如:strcat(s1,"def");
字符串拷贝
- strcpy(数组名,字符串);
引入:
#include <string.h>
说明:
这个函数适合给字符串赋值用
char str[16] = "啦啦啦" ; //正确
char str[16]; str[16] = "啦啦啦"; //错误 赋值
char str[16]; strcpy(str,"啦啦啦");//正确,借用函数完成赋值
案例:
cpp
//字符串的拷贝
//语法:strcpy(数组名,"字符串");
#include <stdio.h>
#include <string.h>
int main()
{
//创建一个char数组,用来存放人的名字
char name[20];
printf("请输入您的名字:\n");
scanf("%s",name);
//fgets 和 scanf只能二选一
fgets (name,sizeof(name)/sizeof(char),stdin);
strcpy(name,"啦啦啦");
printf("您的姓名是:%s\n",name);
return 0;
}
字符串比较
- strcmp(字符串1,字符串2);
引入:
#include <string.h>
功能:
比较两个字符串对应位置字符ASCII的大小(字典顺序比较)。
返回值:
若字符串1 等于
字符串2,返回 0
若字符串1 大于
字符串2,返回正数
若字符串1 小于
字符串2,返回负数
说明:
① 执行这个函数时,自左到右逐个比较对应字符的ASCII的值,直到发现了不同字符或字符串结束符'\0'为止。
② 对字符串不能用数组型比较符
③ 字符串1与字符串2可以是字符数组名,也可以是字符串常量。
案例:
cpp
//字符串的拷贝
//语法:strcmp(字符串1,字符串2);
#include <stdio.h>
#include <string.h>
int main()
{
//创建一个char数组,用来存放账户和密码
char username[20],password[8];
printf("请输入您的账户:\n");
scanf("%s",username);
printf("请输入您的密码:\n");
scanf("%s",password);
if(!strcmp(username,"admin") && !strcmp(password,"123456"))
{
printf("登录成功!\n");
}
else
{
printf("账户或者密码错误!\n");
}
return 0;
}
字符串长度
- strlen(字符串)
引用:
#include <string.h>
注意:
返回字符串中包含的字符的实际个数,不含\0
案例:
cpp
#include <stdio.h>
#include <string.h>
//字符串的长度
//语法:strlen(字符串 | 字符数组)
int main()
{
//创建一个char数组,用来存放账户和密码
char username[20],password[8];
printf("请输入您的账户:\n");
scanf("%s",username);
//获取字符串的长度
unsigned long len = strlen(username)
if(!strcmp(username,"admin"))
{
printf("账户输入正确!%lu\n",len);
}
else
{
printf("账户输入错误!%lu\n",len);
}
return 0;
}