字符串(冬二周——冬四周)
1.字符串基本知识
定义1
char s[6]={'H','e','l','l','o','\0'}
'\0'是八进制字符常数,ascII码=0,作为字符串结束标注
定义2
char s[6]="Hello" //注意必须是双引号,有隐藏'\0',所以s长度为6
'A'与"A"区别
"A"由'A'和'\0'两个元素组成的字符串,而'A'为字符
空串
""称为空串,里面只有一个'\0'
''语法错误
2.字符串输入输出
%s输入输出字符串
char a[100];
scanf("%s",&a[0]); #该语句与scanf("%s",a)等价,a地址与a[0]地址相同
printf("%s",a); #此处a可以理解为数组a的全体内容,直接写printf(a)也可
想要储存一个字符串,必须用一个数组
输入时要给出一个地址,是a[0]的地址,虽然a[0]只能存储一个字符,但scanf在识别到%s时,能后续获得数组后面元素的地址
%s格式会输出'\0'左边的全体元素,但不输出'\0'本身
char a[100]="0123456789ABCDEF";
scanf("%s",&a[0]);
printf(a);
此时输入ABC xyz 123,输出为ABC
这是因为scanf在输入时,以空格为边界输入(将空格理解为分隔符),此时a实际值变为"ABC\0456789ABCDEF\0"
printf输出时,只输出"\0"左边的值,故输出"ABC",实际上字符串还含有其他内容
gets()输入
char a[100];
gets(a); //不可写成a=gets(),因为a不是变量名,而是&a[0]
gets()以回车作为输入的结束标志,而不是空格
以下内容摘自小白网页问题4:
Q:用scanf()的%s格式输入一个字符串跟用gets()输入一个字符串有什么区别?
A:假定已定义数组char a[100],那么scanf("%s", a)与gets(a)有以下区别:
(1) 不输入具体内容直接敲回车时,scanf()会认为此回车是输入项之间的分隔符,故它会过滤掉此回车并继续等待用户输入非空白的内容;而gets(a)则会认为此回车标志着一行内容输入的结束,于是它会执行a[0]='\0';并返回。
(2) 当输入一个含有空格的字符串如ABC xyz 123时,scanf()仅读取"ABC"并保存到a中,其中a[0]='A', a[1]='B', a[2]='C', a[3]='\0',而把" xyz 123"以及回车符(即'\n')留在输入缓冲区中;gets(a)则会把回车前的所有字符全部保存到数组a中,同时丢弃回车符,此时数组a的内容为:a[0]='A', a[1]='B', a[2]='C', a[3]=' ', a[4]='x', a[5]='y', a[6]='z', a[7]=' ', a[8]='1', a[9]='2',a[10]='3', a[11]='\0'。
(3) 当输入一个不含空格的字符串如ABC时,scanf()会读取"ABC"并保存到a中,同时把回车符留在输入缓冲区中;gets(a)也会读取"ABC"并保存到a中,但它会把回车符丢弃,即不会把回车符留在输入缓冲区内。
gets()有返回值,返回字符串第一个字符的地址,输入失败返回NULL
循环遍历输入
char a[100],x;
int i=0;
while ((x=getchar())!='\n')
{
a[i]=x;
i++; //或合成a[i++]=x
}
a[i]='\0'; //只有末尾是'\0'才是字符串
printf(a);
3.字符串函数
头文件
#inlcude <string.h>
strlen
char a[100];
int n;
scanf("%s",&a[0]);
n=strlen(a);
strlen函数返回'\0'左边的元素个数,也是'\0'元素的索引下标
函数实现:
int my_strlen(char a[]) /*这里a是用一维数组做形参,或写成char a[100]*/
{
int i=0;
while (a[i]!='\0')
i++;
return i;
}
int n=my_strlen(a); /*这里的a是用一维数组做实参,只能是a,a[]或a[100]都不行*/
实参和形参可以一样也可以不一样
二维数组形参规则和边定义边赋值的规则相同,行号可空心,列号不可空心,作形参时不管一维数组还是二维数组实际都是指针
strcpy
用于字符串复制
char a[100]="ABC",char b[100];
strcpy(b,a);
上述程序将a[0]到a[3]复制到b[0]和b[3],复制的是'\0'及其左边的元素,这说明假如b[4]之后有其他元素(如b="0123456789"),输出b也只会输出ABC
不允许用加法运算直接拼接
puts
puts(b);
等价于printf("%s\n",b),注意自带回车
有返回值,输出成功返回'\n',输出失败返回EOF
strcat
字符串连接
strcat(b,a);
把a拼接到b后面
strcmp
字符串的比较
int n;
n=strcmp(a,b);
两个字符串元素逐个比较,若a[i]和b[i]不相等,则输出此时a[i]-b[i]的值;若a[i]和b[i]相等,则比较下一个值,直到'\0'或a[i]与b[i]不相等。
n>0,a>b;n=0, a=b;n<0,a<b
在VC和DEVCPP中,strcmp会把大于0的结果转化成1,小于0的结果转换成-1,等于0则返回0
在TC中,strcmp的值是最后那次减法的差
不能用关系运算符比较字符串的大小
4.一些算法
十进制转十六进制数(字符串%s格式输出)
int x=1000;
char a[100];
int i=0;
char t[]="0123456789ABCDEF";
char c;
do /*统计位数或分解整数要用do-while,排除x==0的特殊情况*/
{
d=x%16;
a[i]=t[d]; /*查表实现添引号*/
i++;
x/=16;
}while (x!=0);
a[i]='\0';
n=strlen(a); /*等价于n=i*/
for (i=0;i<n/2;i++)
{
c=a[i];
a[i]=a[n-1-i];
a[n-1-i]=c;
}
printf(a); /*字符串可以直接输出*/
统计单词个数(有空格的单词,空格可能不只1个)
char a[100],b=' ',c; /*b表示before,初始化为空格相当于给字符串最左边加上一个空格*/
int cnt=0,i,n;
gets(a);
n=strlen(a);
for (i=0;i<n;i++)
{
c=a[i];
if (c!=' ' && b==' ')
cnt++;
b=c; /*迭代*/
}
printf("%d",cnt);