字符串:
- C语言的字符串是以字符数组的形态存在的
- 不能用运算符对字符串做运算
- 通过数组的方式可以遍历字符串
- 唯一特殊的地方是字符串字面量可以用来初始化字符数组
- 以及标准库提供了一系列字符串函数
字符串常量:
char * s = “Hello,word”;
- s 是一个指针,初始化为指向一个字符串常量
- 由于这个是常量所在的地方,所以实际上s是const char * s,但是由于历史的原因,编译器接受不带const的写法。
- 但是试图对s所指的字符串做写入会导致严重的后果
- 如果需要修改字符串,应该用数组:
char s[ ] = “Hello,word!”;
#include<stdio.h>
#include<string.h>
int main() {
int i=0;
//字符串变量
char *s = "Hello word";
char *s2 = "Hello word";
char *s3 = "hello word";
/*
字符串会被存储在计算机的代码段,那个地方是只读的
因为s和s2的字符串常量是一样的,所以从输出也可指他们会指向同一个地址;
s3指向的地址不同是因为字符串常量不一样导致的。
*/
char s4[] = "Hello word";
char s5[11]="hello word";
char s6[][10]= {"hello",",","word"};
s4[0]='B';//可以对其进行赋值,但对s,s2,s3不能进行赋值
printf("字"
"符"
"串""\n"
); //相邻的字符串常量会被连接起来
printf("写字符串"
"\"hello word\""
"\n"); // \起到转义的作用
printf("hello\
word""\n");//行末的\表示下一行还是这个字符串常量
printf("s4的长度 %d\n",strlen(s4)); //但是数组的长度为11,因为还有结尾的0
printf("s的地址 %p\n",s);
printf("s2的地址 %p\n",s2);
printf("s3的地址 %p\n",s3);
printf("s4的地址 %p\n",s4);
printf("s4字符串 %s\n",s4);
printf("s4[0] = %c\n",s4[0]);//给s4[0]赋了'B',可以输出赋值后的结果
return 0;
}
输出结果(64位架构):
字符串输入输出:
#include<stdio.h>
int main(){
char str[5];
char sr[5];
char buffer[100]="";//空的字符串,数组长度只有一
scanf("%s",str);//scanf不知道要读入的内容的长度 ,读入一个单词(到空格、tab或回车为止)
printf("%s\n",str);
putchar('\n');
scanf("%3s",str);
/*
在%和s之间的数字表示最多允许读入的字的数量
这个数字应该比数组的大小小一
*/
printf("%s\n",str);
return 0;
}
输出结果:
字符串数组:
char **a//a是一个指针,指向另一个指针,那个指针指向另一个字符(串)
char a[][]//a是一个二维数组,第二个维度不知道大小,不能编译
char a[][10]//a是一个二维数组,a[x]是一个char[10]
char *a[]//a是一个一维数组,a[x]是一个char*
getchar and putchar :
#include<stdio.h>
int main(){
int ch;//
while((ch=getchar())!=EOF){
putchar(ch);//返回int类型
/*
向标准输出写一个字符
返回写了几个字符,EOF(-1)表示写失败
*/
/*
int getchar(void)
从标准输入读入一个字符
返回类型是int是为了返回EOF(-1)
windows——>Ctrl-Z 结束输入
——>Ctrl-C 结束程序
Unix——>Ctrl-D 结束输入
*/
}
printf("EOF\n");
return 0;
}
输出结果:
字符串函数:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char line[]="hello";
char s1[]="abc";
char s2[]="Abc";
char s3[]="abc";
printf("strlen = %d\n",strlen(line));
printf("sizeof = %d\n",sizeof(line));//算了后面的\0
printf("strcmp(s1,s2) = %d\n",strcmp(s1,s2));//s1>s2
printf("strcmp(s1,s3) = %d\n",strcmp(s1,s3));//s1==s3
printf("strcmp(s1,s2) = %d\n",strcmp(s2,s1));//s1<s2
//比较ASCII码的大小
printf("strcpy(s1,s2) = %s\n",strcpy(s1,s2));//返回s2 ,拷贝了s2的字符到了s1
//复制
printf("strcat(s1,s2) = %s\n",strcat(s2,s3));//把s3拷贝到s2后面,返回s2
char *p = strchr(line,'l');
printf("strchr(line,'l') = %s\n",p);
p=strchr(p+1,'l');
printf("strchr(p+1,'l') = %s\n",p);
printf("p = %s\n",p);
char *t = (char*)malloc(strlen(p)+1);
strcpy(t,p);
printf("t = %s\n",t);
free(t);
// 输出line的lo前面的hel的办法如下:
char c=*p;
*p='\0';//从上面:char *p = strchr(line,'l'); 可知p指向l所处的的地址
char *T=(char*)malloc(strlen(line)+1);
strcpy(T,line);
printf("T = %s\n",T);
*p='l';
free(T);
char word[]="hello world";
char *a=strstr(word,line);
/*
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。
如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
所以我们可以用指针去访问地址里的内容
*/
printf("%s\n",a);
/*
因为strstr返回首地址,所以输出的是首地址及首地址之后的所有内容;
*/
return 0;
}
输出结果:
参考资料:C语言——翁恺老师