目录
前言
本篇是针对网上学习字符数组的知识点的总结。
感谢评论区的小伙伴提出的问题,gets()函数输入字符串那里确实有问题。现在gets()函数已经被弃用,因为它是不安全的。我会在文章中写明原因和替换gets()函数的方法。
字符数组
用来存放字符数据的数组是字符数组。
C语言用字符数组存放字符串,字符数组中的各素依次存放字符串的各字符
一维字符数组:存放一个字符串(每个数组素存放一个字符)
二维字符数组:存放多个一维数组(字符串);二维数组的行数是字符串的个数
定义格式: char 数组名[常量表达式];
例如:char c[6]; //c数组具有6个素,可以存放长度小于或等于5的字符串。
char 数组名[常量表达式][常量表达式]; //声明的时候,方括号中一定是常量或常量表达式,使用的时候可以是变量。其中常量表达式:整数、字符、符号常量 。 也可以用整型数组存放字符型数据,但是浪费存储空间。
字符串的存储
例如:char c[10]="c program"; 该数组在计算机中存储的形式为
c[0] | c[1] | c[2] | c[3] | c[4] | c[5] | c[6] | c[7] | c[8] | c[9] |
c | 空格 | p | r | o | g | r | a | m | \0 |
强调:字符串实际占有单的数量等于字符串长度+1。
定义时注意考虑素总个数应比实际长度多1。
字符数组初始化
(一)用单个字符对字符数组初始化
例如:char c[10]={'c',' ', 'p','r','o','g','r','a','m','\0'}; //把10个字符依次赋给c[0]~c[9]这10个素
内存中存储情况:
c[0] | c[1] | c[2] | c[3] | c[4] | c[5] | c[6] | c[7] | c[8] | c[9] |
c | p | r | o | g | r | a | m | \0 |
说明:
- 如果在定义字符数组时不进行初始化,则数组中各素的值是不可预料的
- 如果花括号中提供的初值个数(即字符个数)大于数组长度,则出现语法错误
- 如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度
- 如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些素,其余的素自动定为空字符(即'\0')
(二)用字符串常量对字符数组初始化
例如:(1)char str[6]={"CHINA"};
(2)char str[6]="CHINA"; //省略{}
(3)char str[ ]="CHINA"; // 省略长度值
(4)char c[12]={"HOW ARE YOU"};
与char c[ ]={'H','O','W',' ','A','R','E',' ','Y','O','U','\0'}; 等价
(5)char *p=c; //用一个指针指向该数组,*(p+i) <=> a[i]
说明:
- 将字符串存储到字符数组中,字符串和第一个'\0'构成有效字符串。对字符串的操作,就说对字符数组的操作
- 普通数组中的素是确定的,一般用下标控制循环;而字符串使用结束符'\0'来控制循环
字符数组的输入输出
1、单个字符输入输出(用格式符%c或字符输入函数)
#include<stdio.h> int main() { char c[5]; int i; for(i=0;i<5;i++) scanf("%c",&c[i]); for(i=0;i<5;i++) printf("%c",c[i]); printf("\n"); return 0; }
输入 | China |
输出 | China |
输入 | Program |
输出 | Progr |
(2)字符串整体或部分输入输出(用格式符%s)
#include<stdio.h> int main() { char str[5]; scanf("%s",str); printf("%s",str); }
说明:
不需要用循环语句进行输入输出操作
输入输出项必须是以字符串的地址形式出现,也可以是字符串常量:printf("%s\n","book");
输入时:
- 数组名前不加&符号
- 输入字符串的长度要小于数组长度
- 只能输入不包括空格、\t和\n的字符串
- 若要输入空格,用gets函数
- 自动加'\0'
例如:
#include<stdio.h> int main() { char str[13]; scanf("%s",str); printf("%s",str); }
输入:CHINA IS GOOD 输出:CHINA
输出时:遇'\0'结束
字符串处理函数
包含在头文件 string.h 中
·字符串输出函数 puts
格式: puts(字符数组)
功能:向显示器输出一个字符串(输出完,换行)
说明:字符数组必须以'\0'结束。可以包含转义字符。输出时'\0'转换成'\n',即输出字符后换行。
#include<stdio.h> #include<string.h> int main() { char a[]={"china\ngood"}; char b[]={"zhong\0guo"}; puts(a); puts(b); puts("CHINA"); }
运行结果: china good zhong //将'\0'转换成'\n' CHINA
·字符串输入函数gets(不安全,尽量别用)
格式:gets(字符数组)
功能:从键盘输入一个以回车结束的字符串放入字符数组中,并自动加'\0'
说明:输入串长度要小于字符数组长度
注意:puts和gets函数只能输入输出一个字符串. 不能这样:puts(a1,a2); gets(a1,a2);
#include<stdio.h> #include<string.h> int main() { char a1[10],a2[10]; gets(a1); scanf("%s",a2); printf("a1=%s\n",a1); printf("a2=%s\n",a2); }
输入: china china //在scanf中遇到空格字符串便结束了,而gets中,却将空格作为字符存放入字符数组中 china china 输出: a1=china china a2=china
在上面的例子中,给a1输入了11个字符,明显超出了声明a1时给a1分配的空间。但是当我在自己的编译器上运行时,a1的输出是china china,与输出一致。但是这明显是有问题的。
然后我又输入了位数更多的字符串:,但是a1的输出仍然与输入一致。那么,为什么会这样呢?
gets()函数原型:char *gets(char *str);
gets() 函数的功能是从输入缓冲区中读取一个字符串存储到字符指针变量 str 所指向的内存空间。它可以无上限地读取缓冲区的字符串,并且它不能判断读入的字符串大小,当输入回车时,它的读取才结束。
它的不安全之处正是由于它的无限读取。若输入的字符串不超出缓冲区的话还好,但是一旦发生缓冲区溢出,会引起程序崩溃。
·gets()函数的替代方法
·fgets()函数
功能:从指定的文件中读取字符串,也可从用户的输入中读取字符串。
一般用法:
char a[100]; fgets(a,100,stdin); //从用户的输入中读入最多100个字符,其中包含'\n',且字符串的最后一个 //一定是以'\0'结尾
具体地大家可以参看这篇博客
·getchar()函数+循环
getchar()是C语言的库函数,原型:int getchar(void);
功能:读入缓存区的一个字符。
返值:以无符号 char 强制转换为 int 的形式返回读取的字符。
用途一:用getchar函数读取单个字符。
#include<stdio.h> #include<string.h> int main() { char a; printf("输入的字符:"); a = getchar(); printf("输出的字符:"); putchar(a); return 0; }
输入的字符:a 输出的字符:a
用途二:从键盘输入的回车键也算是一个字符,此时可用getchar()函数消掉缓存区的回车键,以免对之后的输入造成影响。
#include<stdio.h> #include<string.h> int main() { char a[10] = {0}; char c; int i=0; printf("请输入字符数组a:\n"); for(i=0;i<10;++i) { scanf("%c",&a[i]); } printf("请输入字符c:\n"); scanf("%c",&c); puts(a); if(c == '\n') printf("\\n"); else printf("%c",c); return 0; }
输出: 请输入字符数组a: 请输入字符c: \n
这种情况就是字符c读取了用户键入缓存区的回车键,c中存取的字符为'\n'。
为了消除回车键的影响,可以使用getchar()函数。
#include<stdio.h> #include<string.h> int main(void) { char a[10] = {0}; char c; int i=0; printf("请输入字符数组a:\n"); for(i=0;i<10;++i) { scanf("%c",&a[i]); } getchar(); //getchar函数消除回车键的影响 printf("请输入字符c:\n"); scanf("%c",&c); puts(a); if(c == '\n') printf("\\n"); else printf("%c",c); }
输出: 请输入字符数组a: 请输入字符c: c c
用途三:用getchar函数读取字符串。
#include<stdio.h> #include<string.h> int main() { char a[100],c; int i=0; while((c = getchar()) != '\n') { a[i] = c; //或者花括号中直接写a[i++] = c; i++; } //第一种输出方法 printf("%s",a); puts(""); //起到换行的作用 //第二种输出方法 for(i = 0; i<strlen(a);++i) //strlen()函数后文有讲 printf("%c ",a[i]); printf("\n"); //第三种输出方法 puts(a); return 0; }
输入:123 输出: 123 1 2 3 123
·用scanf + 循环
#include<stdio.h> #include<string.h> int main() { char a[100],c; int i=0; while(scanf("%c",&a[i]) && a[i]!= '\n') { i++; } //第一种输出方法 printf("%s",a); puts(""); //第二种输出方法 for(i = 0; i<strlen(a);++i) //strlen()函数后文有讲 printf("%c ",a[i]); puts(""); //第三种输出方法 puts(a); return 0; }
输入:123as 输出:123as
·字符串连接函数strcat
格式:strcat(字符数组1,字符数组2)
功能:把字符数组2连到字符数组1后面
返值:返回字符数组1的首地址
说明:
- 字符数组1必须足够大
- 连接前,两串均以'\0'结束;连接后,串1的'\0'取消,新串最后加'\0'。
#include<stdio.h> #include<string.h> int main() { char str1[10]={"China is"}; char str2[]={"good"}; printf("%s\n",strcat(str1,str2)); } 输出: China is good
str1: | China is\0 |
str2: | good\0 |
str1: | China is good\0 |
·字符串拷贝函数strcpy
格式:strcpy(字符数组1,字符串2)
功能:把字符数组2,拷贝到字符数组1中去
返值:返回字符数组1的首地址
说明:
- 字符数组1必须足够大,至少大于字符串2
- 字符数组1必须是数组名形式(str1),字符串2可以是字符数组名或字符串常量
- 拷贝时'\0'一同拷贝
- 一般形式
#include<stdio.h> #include<string.h> int main() { char str1[20],str2[]="Hello!"; strcpy(str1,str2); printf("%s\n",str1); printf("%d\n",strlen(str1)); printf("%d\n",sizeof(str1)); }
Hello! 6 20 //总长度
·字符串比较函数strcmp
格式: strcmp(字符串1,字符串2)
功能:比较两个字符串
比较规则:对两串从左向右逐个字符比较(ASCII码),直到遇到不同字符或'\0'为止
返回值:返回int型整数。其值是ASCII码的差值(根据编译器的不同,也有可能返回1,0,-1)
若字符串1大于字符串2,返回正整数;
若字符串1等于字符串2,返回零;
若字符串1小于字符串2,返回负整数;
说明:字符比较必须用strcmp
#include<stdio.h> #include<string.h> int main() { char a[]={"china"},b[]={"henan"}; int x.y.z; x=strcmp(a,b); y=strcmp("china","beijing"); z=strcmp(a,"china"); printf("x=%d\ny=%d\nz=%d\n",x,y,z); return 0; }
x=-1 //只比较了c与h的ASCII码值,在ASCII码表中,c的值小于h的值 y=1 // 在ASCII码表中,c的值大于b的值 z=0
·字符串长度函数strlen
strlen是函数,要在运行的时候才能计算。参数必须是字符型指针。当数组名作为参数传入时,实际上数组就退化成指针了
格式: strlen(字符数组)
功能:返回字符串的长度。该字符串可能时自己定义的,也可能时内存中随机的,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。
返值:返回字符串实际长度,不包括‘\0’在内
#include<stdio.h> #include<string.h> int main() { char a[]="china"; printf("%d\n",strlen(a)); printf("%d\n",sizeof(a)); }
输出:
5 //china后面自带'\0',strlen返回的字符串长度不带'\0' 6
·字符串处理函数(strlwr函数与strupr函数)
strlwr函数:
格式:strlwr(字符串)
作用:将字符串中的大写字母换成小写字母
strupr函数:
格式:strupr(字符串)
作用:将字符串中的小写字母换成大写字母
总结
字符数组的相关内容就总结到这里吧,欢迎大家批评指正。
今天的文章 C语言之字符数组分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/103259.html