一.字符数组的初始化
'\0':代表ASCII码为0的字符,仅仅是一个供辨识的标志,代表字符串结束
字符串:双引号 字符:单引号
char c[ ]={"happy"}; = char c [ ]="happy";
=
char c[ ]={'h','a','p','p','y','\0'}; = char[6]={'h','a','p','p','y'};
二.字符数组的输入输出
1.逐个字符输入输出,用格式符“%c”输入输出
2.将整个字符串一次输入或输出,用格式符“%s”(string 字符串)
*输入*
1.scanf函数
格式:scanf(“%s”,字符数组)
功能:输入以空格或回车结束的字符串放入字符数组中,并自动加\0
输入项如果是字符数组名,不要再加取地址符&!因为C语言中数组名就代表该数组第一个元素的地址。
如果要用一个scanf输入多个字符串。要在输入时以空格分隔
eg:char str1[5],str2[5],str3[5];
scanf("%s%s%s",str1,str2,str3);
输入数据 :How are you?
如果是:
char str[13];
scanf("%s",str);
2.gets函数
格式:gets(字符数组首地址)
功能:以回车结束的字符串放入字符数组中,并自动加'\0'
eg: char str[81];
gets(str);
输入I love China! 回车时,str中的字符串就是"I love China!"
*输出*
1.puts函数
格式:puts(字符串地址)
功能:像显示器输出字符串(输出完,换行)
说明:如果是字符数组,必须以'\0'结束
比如:
1.char str[ ]="Hello";
puts (str);或者puts(“Hello”);
如果是char str[]={'h','e','l','l','o','\0'};//字符数组 初始化没有确定长度的时候不要忘记加'\0'
***puts和gets函数只能输入或者输出一个字符串!***
2.printf函数
格式:printf("%s",字符串地址)
功能:依次输出字符串中的每个字符直到遇到字符'\0',\0不会被输出
eg:char str[ ] = "Hello";
printf("%s\n",str); 输出结果:Hello // 和scanf函数一样 数组名就代表该数组第一个元素的地址 str[0]
printf("%s\n",&str[2]); 输出结果:llo
printf("Hello"); 输出结果:Hello
练习
1.不带空格的字符串
2.带空格的字符串
3.输出字符串的每个字符
#include <stdio.h>
int main()
{
1.输出不含空格的
char s[25];
while(~scanf("%s",s)){
puts(s);
}
2.输出含空格的
char (s[255];
while(gets(s)){
puts(s);
//=printf("%s\n",s);}
3.遍历字符数组
char s[25];
while(~scanf("%s",s)){
for(int i =0;s[i]!='\0';i++){
printf("%c\n",s[i]);
//= putchar(s[i]);
}
}
return 0;
}
三.其他函数
1.strlen函数(string+length 字符串长度)
测量字符串的实际长度,不包括'\0'在内
eg:char str[10]="china";
printf("%d",strlen(str)); 输出的结果是5
例一:统计数字字符个数
#include <stdio.h>
#include <string.h>
int main()
{
char s[25];
gets(s);
int n=strlen(s),x=0;
for(int i=0;i<n;i++){
if(s[i]>='0'&&s[i]<='9'){
x++;
}
}
printf("%d",x);
return 0;
}
**这里面的i<n,如果是用i<strlens(s)也可以,只是strlens本质也是循环来计算个数,再写到下一个循环了就要重复计算降低效率了。**
2.strcpy(string+copy)-字符串复制函数
将字符串2复制到字符串1中去.
eg:char str1[10],str2 [ ] = "China";
strcpy(str1,str2);
执行后,str1:
**(1):字符数组1必须定义的比字符串大
(2):’字符数组1必须写成数组名形式‘:如str1,’字符串2‘可以是字符数组名,也可以是一个字符串常量,如strcpy(strl,"China");
(3)不能用赋值语句将一个字符串常量或者是字符数组直接给一个字符数组。字符数组名是一个地址常量(之前要在输入中使用取地址符&就是为了获得变量的地址),不能改变值。
像:str1="China";(想用赋值语句将一个字符串常量直接赋值给一个字符数组)
或:str1=str2; (想用赋值语句将一个字符数组直接赋值给一个字符数组) 都是错误的
赋值语句仅仅可以将单个字符赋给一个字符型变量或字符型数组元素;
如:char c1,c2; c1='A',c2='B';
(4)strncpy函数可以将字符串2中前面n个字符复制到字串数组1中去
strncpy(str1,str2,2); 可以将str2中最前面的2个字符取代str1原有的最前面2个字符。
3.strcmp函数(string+compare)-字符串比较函数
格式:strcmp(字符串1,字符串2)
比较规则:两个从左向右逐个字符比较(按ASCII码值大小比较)直到出现不同的字符或是遇到'\0'为止。
返值:返回int类型整数 若字符串1>字符串2 ,返回1 如(strcmp("abcd","abCD");
字符串1<字符串2,返回-1 如(strcmp("1234","12345");
字符串1=字符串2,返回0 如(strcmp("hello","hello");
**小写字母的ASCII值比大写字母大**
注意:不能使用:if(str1>str2)因为str1和str2代表的是地址还不是数组中的全部元素,只能用
if(strcmp(str1,str2)>0) 此时,系统找到两个字符数组的第一个元素,然后顺序比较数组中的各个元素的值。
4.strcat函数(string+catenate)--字符串连接函数
格式:strcat(字符数组1,字符数组2)
功能:把字符数组2连接到字符数组1后面
返值:返回字符数组1的首地址
注意:1.字符数组1必须定义的足够大,上述例子中不可以定义成char str1="People's Republic of" 连接时长度不够
2.连接前,两串均以'\0'结束;连接后,串1的'\0'取消,新串最后加上'\0'
例二:将一个字符串str的内容颠倒并输出,str的长度不超过100个字符。
#include <stdio.h>
#include <string.h>
int main()
{
char s[25];
gets(s);
int n=strlen(s);
for(int i=0;i<n/2;i++){
char c=s[i];
s[i]=s[n-i-1];
s[n-i-1]=c;
}
puts(s);
}
例三:身份证号码判断性别
//C:身份证号码
#include <stdio.h>
#include <string.h>
int main()
{
int n;
char s[30];
scanf("%d",&n);
// scanf("%d\n",&n); 用gets读入会读入回车符号 输入时加一个\n吸收换行符
for(int i=0;i<n;i++){
// gets(s);
scanf("%s",s);
if((s[16])%2==0){
printf("loli\n");
}
else if(s[16]%2==1){
printf("shota\n");
}
}
return 0;
}
例四:纠正英文语句中的大小写拼写错误
输入英文语句,以换行符号作为结束(语句长度不超过50,并且第一个单词之前没有空格或其他符号)
//E: 纠正英文语句中的大小写拼写错误
#include <stdio.h>
#include <string.h>
int main()
{
char s[55];
gets(s);
int x=strlen(s);
//首字母小写改成大写
if(s[0]>='a'&&s[0]<='z')
{
// char c1=s[0];
// char c2=c1-32;
// s[0]=c2;
//不需要考虑ASCII表 直接这样写
s[0]=s[0]-'a'+'A';
}
//其他情况全部改成小写
for(int i=1;i<x;i++){
if (s[i]>='A'&&s[i]<='Z'){
// char c1=s[i];
// char c2=c1+32;
// s[i]=c2;
s[i]=s[i]-'A'+'a';
}
}
puts(s);
return 0;
}
例五:首字母缩略词
#include<stdio.h>
#include <string.h>
int main()
{
char s[205];
gets(s);
int n=strlen(s);
if(s[0]>='A'&&s[0]<='Z'){//首字母直接是大写不变
printf("%c",s[0]);
}
else{
s[0]=s[0]-'a'+'A';//首字母小写转大写
printf("%c",s[0]);
}
for(int i=1;i<n;i++){
if(s[i]==' '){
if(s[i+1]>='A'&&s[i+1]<='Z'){
printf("%c",s[i+1]);
}
else{
s[i+1]=s[i+1]-'a'+'A';
printf("%c",s[i+1]);
}
}
}
return 0;
}
四.字符串数组
例六:查找人名
输出:No
**如何将最后一个名字和之前的几个依次比较呢**
想使用strcmp函数,但是该函数是字符串与字符串的比较,想到使用字符型二维数组
**在这之前,先看看如何使用devc++来查看数组变量值**
1.先看一个基本的一维数组:
如输入:1 2 3
想要看整个输入数组的值 :调试中 添加查看*(&a[0])@3 ={1,2,3}//第0行 数组长度为3
想看数组值随i的变化改变的:*(&a[i])
2.看一下二维数组的调试
这样的一个基本的两行两列的二维数组
#include <stdio.h>
#include <string.h>
int main()
{
int n;
scanf("%d",&n);
char s[n+5][25],c[25];
for(int i=0;i<n;i++){
for(int j=0;j<25;j++){
scanf("%s",s[i]);
}
}
scanf("%s",c);
for(int i=0;i<n;i++){
if(strcmp(s[i],c)==0){
printf("Yes");
break;
}
else{
printf("No");
break;
}
}
return 0;
}
例题七:ROT13密码
#include <stdio.h>
#include <string.h>
int main()
{
char s[55];
gets(s);
int n=strlen(s);
for(int i=0;i<n;i++){
if(s[i]>='a'&&s[i]<='m'||s[i]>='A'&&s[i]<='M'){
s[i]=s[i]+13;
}
else if (s[i]>='N'&&s[i]<='Z'||s[i]>='n'&&s[i]<='z'){
s[i]=s[i]-13; //这里一定要写else if 只用if就相当于上一个if语句运行完了 然后接着这一步if 那么就相当于又复原了才会输出一样的字符串
}
}
puts(s);
return 0;
}
如果是是用一个新的数组来拷贝,要注意非字母情况还需要拷贝,而且还需要对新的数组初始化
#include <stdio.h>
#include <string.h>
int main()
{
char s[55],a[55]={0};//这里相当于拷贝了一份s[i]到a[i]里
gets(s);
int n=strlen(s);
for(int i=0;i<n;i++){
if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')){
if((s[i]>='a'&&s[i]<='m')||(s[i]>='A'&&s[i]<='M')){
[i]=s[i]+13;
}
if((s[i]>='N'&&s[i]<='Z')||(s[i]>='n'&&s[i]<='z')){
a[i]=s[i]-13;
}
}
else{
a[i]=s[i];
}
}
puts(a);
return 0;
}