文章目录
- 字符串
- 基本概念
- 定义和初始化
- 字符串输入输出
- 如下格式均可实现输入输出
- 字符串遍历
- 操作
- 字符串和字符指针
- 字符指针的赋值引用
- 通用的字符串处理函数
- 输入
- 输出
- 复制 连接 比较 求长度
- 链接
- 比较
- 长度
- 查找替换
字符串
基本概念
1.C语言字符串本质就是数组的延伸,以**‘\0’**结尾的字符数组,空字符NULL的ascii码为0
定义和初始化
// 方式1:指定大小并初始化,剩余自动补'\0'charstr1[20]="Hello, World!";// 方式2:不指定大小,编译器自动计算charstr2[]="Hello, World!";// 方式3:逐个字符初始化charstr3[]={'H','e','l','l','o','\0'};str 在内存当中如下存储: 0: 'H' 1: 'e' 2: 'l' 3: 'l' 4: 'o' 5: ',' 6: ' ' 7: 'W' 8: 'o' 9: 'r' 10: 'l' 11: 'd' 12: '!' 13: '\0' // 字符串结束符 14: '\0' // 自动填充的'\0' 15: '\0' // 自动填充的'\0' 16: '\0' // 自动填充的'\0' 17: '\0' // 自动填充的'\0' 18: '\0' // 自动填充的'\0' 19: '\0' // 自动填充的'\0'字符串有效长度的个数就是有效字符的个数,不包括\0
字符串输入输出
如下格式均可实现输入输出
#defineMAXLINE80intstr[MAXLINE];inti=0;while((str[i]=getchar())!='\n'){//回车即停止输入i++;}str[i]='\0';//很关键getchar手动输入必须要添加’\0’!!
#defineMAXLINE80intstr[MAXLINE];// 使用scanf输入(遇到空格停止)printf("Enter a string (no spaces): ");scanf("%s",str);printf("You entered: %s\n",str);#defineMAXLINE80intstr[MAXLINE];// 使用fgets输入(可以包含空格)printf("Enter a string (can have spaces): ");fgets(str,sizeof(str),stdin);printf("You entered: %s",str);这两种方法均会在结尾自动添加’\0’
以下三种等价
static char s[6] = { ‘H’, ‘a’, ‘p’, ‘p’, ‘y’ };
static char s[6] = { ‘H’, ‘a’, ‘p’, ‘p’, ‘y’, 0 }; 0代表字符’\0’,也就是ASCII码为0 的字符
static char s[6] = { ‘H’, ‘a’, ‘p’, ‘p’, ‘y’, ‘\0’ };
字符串由有效字符和字符串结束符’\0’组成
使用字符串常量
static char s[6] = { “Happy” };
static char s[6] = “Happy”;
*字符串有效长度就是有效字符的个数,不包括\0,数组长度大于等于有效长度+1
字符串遍历
循环条件:s[i]!=‘\0’
包含字符串空格,不包含结尾\0。
操作
#defineM26sancf("%d",offset);if(offset>=M){offset%=26;//移位相当于取余数}for(inti=0;str[i]!=0;i++){if(str[i]>='A'&&str[i]<='Z'){if((str[i]-'A'+offset)<M){str[i]=str[i]+offset;}else{str[i]=str[i]+offset-M;//直接在整数层面操作}}elseif(str[i]>='a'&&str[i]<='z'){if((str[i]-'a'+offset)<M){str[i]=str[i]+offset;}else{str[i]=str[i]+offset-M;//直接在整数层面操作}}}最终要输出一个数字,s[i] - '0’恰好为这个和数字的整数值,‘9’ - ‘0’ = 9 = ‘九的ASCII码’
进制转换模板
字符串和字符指针
“array”
“point”
用一对双引号括起来的字符序列
被看作一个特殊的一维字符数组,在内存中连续存放。
实质上是一个指向该字符串首字符的指针常量
%s的灵活使用
charsa[]="array";char*sp[]="point"//输出printf("%s",sa);//输出arrayprintf("%s",sp);//输出“point”printf("%s","string");//“输出string”printf("%s",sa+2);//输出rasyprintf("%s","string"+1)//输出tring//sa + 1指向第二个元素在上述过程,sa所代表的字符串,只能改变数组元素的内容
如果要改变指针sp所代表的字符串,通常直接改变指针的值,可以指向新的字符串
char*sp="This is a string";strcpy(sa,"Hello");//来自<string.h>sp="Hello";==sa = “Hello”==非法,数组名是常量,不能赋值
字符指针的赋值引用
定义字符指针后如果没有对他赋值,指针的值不确定,不可以引用
char*s;scanf("%s",s);//不可以这样写char*s,str[20];s=str;scanf("%s",s);//应该这么写//定义指针变量时,想将它的初值置为空char*s=NULL;通用的字符串处理函数
输入
<stdio.h>(fgets fputs)
<string.h>(其他的操作)(strcspn等等)
手动循环输入
charstr[80];inti=0;while((str[i]=getchar())!='\n'){i++;}str[i]='\0';scanf(“%s”,str);可能会引起越界,不加取址运算符,遇到回车或空格输入结束,自动将输入的一串字符和’\0’送入数组str
scnaf(“[^\n]”,str)这样可以读入空格
scanf(“%79[^\n]”,str) 可以控制输入长度gets(str)遇到回车输入结束,并自动将输入的一串字符和’\0’送入数组str,不会检查是否越界,慎用
fgets 非常好用 会读取换行符并存储
实际存储示例:
如果输入"hello"然后按回车,fgets会存储:'h' 'e' 'l' 'l' 'o' '\n' '\0'intlen1=0;while(s1[len1]!='\0'&&s1[len1]!='\n')len1++;s1[len1]='\0';这样可以实现将末尾换行符改为’\0’.此时有两个’\0’
char*fgets(char*string,intn,FILE*string)//成功返回值时字符串指针,即传入的参数str//失败返回NULL指针charstr[80];fgets(str,sizeof(str),stdin);//用法//去掉回车str[strcspn(str,'\n')]='\0';
输出
手动循环输出
charstr[80];inti=0;for(i=0;str[i]!='\0';i++){putchar(str[i]);}printf(“%s”,str);
printf(“%s”,“Hello”);
puts(str)
puts(“hello”)
fputs
intfputs(constchar&str,FILE*string)//string 是输出流,通常用stdout标准输出//返回值是整型数(0或正数)//失败返回EOF(-1)磁盘空间不足,文件流错误或者其他错误fputs(str,stdout);
输出字符串后自动换行,输出参数可以是字符数组名或字符串常量,以’\0’结束
复制 连接 比较 求长度
- 复制 strcpy(str1,str2) str2复制到str1中
- 连接 strcat(str1,str2)
- 比较 strcmp(str1,str2)
- 长度 strlen(str)
- 查找替换 strcspn
- 以上来自<string.h>
链接
strcat(str1,str2);
连接两个字符串str1和str2,并将结果放入str1中
自动去掉str1末尾的’\0’
#include<stdio.h>#include<string.h>intmain(){charstr1[80],str2[20];gets(str1);gets(str2);strcat(str1,str2);puts(str1);return0;}//str1中:Let us\0//str2中:go.\0// str1中:Let us go.\0// str2中:go.\0比较
strcmp(str1,str2);
比较两个字符串str1和str2的大小,按照字典顺序(ASCII码序)对str1和str2对应位置的字符从左到右依次进行比较,第一个不同的字符的ASCII码值更大的大小决定了整个字符串的大小,所有字符相等,str1,str2相等。
- 相等 返回0
- str1 > str2 返回1
- str1 < str2 返回-1
注意,如果单独比较字符数组的名字,则比较的是字符串首元素的地址
手动实现
#include<stdio.h>intmain(){chars1[]="JEI JING";chars2[]="JING";inti,j;intflag=0;i=0;while((s1[i]!='\0')&&(s2[i]!='\0')){//循环条件,均有意义if(s1[i]!=s2[i]){flag=s1[i]-s2[i];break;//第一个不一样的元素}i++;}if((s1[i]=='\0')&&(s2[i]!='\0'))flag=-1;if((s1[i]!='\0')&&(s2[i]=='\0'))flag=1;//这两个if判断是否长度不一样//长度更短的更小if(flag>0)printf("s1 > s2\n");elseif(flag==0)printf("s1 == s2\n");elseprintf("s1 < s2\n");return0;}长度
strlen(str) 计算有效长度,不包含’\0’
strlen(“hello”) = 5;
手动实现
#include<stdio.h>intmain(){chars[101];intI;gets(s);I=0;while(s[I++]);//实现循环统计,先返回I,再实现I++//检测到'\0'就停止gets自动加上I--;//I就是字符串长度}查找替换
strcspn(数组名,查找元素)返回此下标
input[strcspn(input,"\n")]='\0';