字符串
在计算机应用中,除了要处理大量的数值型数据外,还不可避免地要处理大量的文字信息。比如,学校的学籍管理系统在存储学生成绩的同时,还应存储学生姓名、性别、家庭住址等相关信息。通常文字在计算机中是用字符串来表示的。
1.字符串常量
用双引号括起来的一串字符就是字符串常量,它的末尾将由系统自动添加一个字符串结束标志‘\0’。‘\0’作为转义字符,其ASCII码值为0,是一个非显示字符,也称为“空字符”,在使用中与数字0、预定义标识符NULL具有相同的作用。它表示字符串到此结束,因此利用它可以很方便地测定字符串的实际长度。
例如:字符串常量“program”中共有7个字符,串的长度就是7。但是它在内存中要占8个字节的存储单元,最后一个留给‘\0’。又如,两个连续的双引号“”代表的是“空串”,它的长度是0,但也要占据一个存储单元放’\0’。
在C语言中,没有专门的字符串变量,通常用一个字符数组来存放一个字符串变量。
2.字符数组与字符串的区别
字符数组与字符串在本质上的区别就在于“字符串结束标志”的使用。字符数组中的每个元素都可以存放任意的字符,并不要求最后一个字符必须是‘\0’。但作为字符串使用时,就必须以‘\0’结束,因为很多有关字符串的处理都要以‘\0’作为操作时的辨别标志,缺少这一标志,系统并不会报错,有时甚至可以得到看似正确的运行结果。但这种潜在的错误可能会导致严重的后果。因为在字符串处理过程中,系统在未遇到串结束标志之前,会一直向后访问,以致超出分配给字符串的内存空间二访问到其他数据所在的存储单元。
3.通过赋初值为字符数组赋字符串
一个字符型一维数组中的内容能否作为字符串使用,关键是看数组有效字符后面是否加入了串结束符‘\0’。数组定义并赋初值的形式不是唯一的。在某些情况下,系统会自动加入‘\0’;在另一些特定情况下,就需要人为加入‘\0’。
(1)所赋初值个数少于元素个数时,系统会自动加‘\0’。例如:
char c[10]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’};
当然也可以人为加入‘\0’:
char c[10]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’,’\0’};
以上两种赋值形式的效果是相同的。但若定义成:
char c[7]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’};
则数组c不能作为字符串使用,只能作为一维数组使用,因为数组中没有存放结束标志的空间了。
(2)若采用单个字符赋初值来决定数组大小的形式,一定要人为地加入‘\0’。例如:
char c[ ]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’,’\0’};
这时系统为数组c开辟了8个存储单元。但若定义成:
char c[ ]={‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’};
则系统只为数组c开劈7个存储单元,没有存放’\0’的存储空间,c也不能作为字符串使用。
(3)可以在定义时直接赋字符串常量,这是不用人为加入‘\0’,但必须有存放‘\0’的空间。
例如:
char str1[15]={“I am happy”};
数组str1的长度为15,str1[10]~str1[14]自动存放‘\0’。也可以省略花括号,直接写成:
char str1[15]=“I am happy”;
还可以省略数组长度,由字符串常量来决定数组元素的个数。即:
char str2[ ]=“I am happy”;
因为系统自动为字符串常量添加串结束标志’\0’,所以字符数组str2的会占用11个内存单元。但若写成
char str3[10]=“I am happy”;
则数组str3不能作为字符串使用,因为虽然系统在字符串常量末尾自动添加串结束标志‘\0’,但数组中已经没有存放它的空间了。
4.字符串数组
程序设计中经常要用到字符串数组。例如,数据库的输入处理程序就要将用户输入的命令与储存在字符串数组中的有效命令比相比较,检验其有效性。
可用二维字符数组的形式建立字符串数组,行下标决定字符串的个数,列下标决定串的最大长度。
例如,下面的语句定义了一个字符串数组,它可以存放30个字符串,串的最大长度为80个字符:
char str_array[30][80];
要访问单独的字符串是很容易的,只需标明行下标就可以了。下面的语句以数组str_array中的第三个字符串为参数调用函数gets();
gets(str_array[2]);
该语句在功能上等价于:
gets(&str_array[2][0]);
5.例题:输入任意长度(不超过100个字符)的三个字符串,要求统计出其中共有多少个大写字母、小写字母、空格、数字和其它字符。
算法分析:
一个一维字符数组可表示一个字符串,一个二维字符数组可表示多个字符串。所以三个不超过100个字符的字符串就可以用数组char str[3][100]来表示。
首先要输入三个字符串,也就是给字符数组str[3][100]的各行输入字符串初值,然后对字符数组str中的每个字符进行判断是哪一种字符,判断条件如下:
是否为大写字母的条件:‘A’<=str[][j]<=‘Z’;
是否为小写字母的条件:‘a’<=str[][j]<=‘z’;
是否为数字的条件:‘0’<=str[][j]<=‘9’;
是否为数字的条件:str[][j]==’ ‘;
源程序:
#include<stdio.h>
#include<string.h>
main()
{
char str[3][100];
int up=0,low=0,space=0,num=0,other=0,i,j;
for(i=0;i<3;i++)
{
printf("input the %dth string",i+1);
gets(str[i]); /*输入字符串*/
}
for (i=0;i<3;i++)
for(j=0;j<strlen(str[i]);j++)
{
if(str[i][j]>='A'&&str[i][j]<='Z')
up++;
else if(str[i][j]>='a'&&str[i][j]<='z')
low++;
else if(str[i][j]>='0'&&str[i][j]<='9')
num++;
else if(str[i][j]==' ');
space++;
else
other++;
}
printf("大写字母,小写字母,数字,空格,其他字符分别有:\n");
printf("up=%d,low=%d,num=%d,space=%d,other=%d\n",up,low,num,space,other);
return 0;
}