字符串
C语言中没有一种基础数据类型为字符串,字符串是内存中的一串字符且以 ‘\0’ 为结束标识的字符
表现形式:
- 字符串字面值:“hello”
① 凡是在程序中以 “xxx” 出现的字符串,就是字面值字符串
② 字面值字符串,保存在代码区 且 字面值不能修改
③ 相同的字面值字符串,只会存储一份
sizeof(“hello”) == 6字节 ‘h’ ‘e’ ‘l’ ‘l’ ‘o’ ‘\0’
字面值分类:
字符字面值: '0' 'a' 'A' '\n' '\0' ...
整数字面值: 3 023 0x3af 3l 3ul 3ull ...
浮点字面值: 3.14 3e8 1.3e18 3.14f ...
- 字符数组: char s[10]
① 定义一个字符数组,数组中存储一个字符串的内容
② 字符数组保存在栈区 可以修改
③ 初始化方式: 数组长度一定要足够长,保存得下’\0’```c
char s1[10] = "hello";
char s2[10] = {'h','e','l','l','o'};
char s3[] = "hello";
char s4[5] = {'h','e','l','l','o'}; //错误的形式
char s5[5] = "hello"; //错误的形式
- 字符指针: char *p
char *p = "hello"; //指针变量存储的地址是字符串字面值的地址
指针指向字面值字符串不能对字符串的内容进行修改一旦修改:*p = ‘x’; // 100%导致 段错误(核心已转储)
p = “world”;
char s[10] = {‘h’,‘e’,‘l’,‘l’,‘o’};
p = s; //指向栈区的字符串
注意: 千万注意要 ‘\0’
printf("%s",字符串的地址)
输出字符串时,占位是 %s ,参数是字符串的首位置
%s 输出至 '\0' 结束
如果在内存中一直没有遇到'\0' ,会一直输出 ,可能会导致程序崩溃
字符串操作: #include <string.h>
- 字符串的长度(字符个数)
size_t strlen(const char *s); //求得字符串里字符的个数 不包括'\0'
//中文汉字是多字节字符
//size_t == unsigned int 类型
sizeof 与 strlen的区别:
sizeof是求变量、数组、指针、数据所占内存的字节数量。
strlen是求一个地址到内存中到’\0’为止有多少个字符。
(求从一个内存地址开始内存中连续非’\0’字符的个数 ,就是求字符串长度)
strlen函数原型:
size_t strlen(const char *s){
assert(s!=NULL); //if(s==NULL){return -1;}
size_t cnt = 0;
while(s[cnt] != '\0'){ // *(s+cnt) 数组表示
++cnt;
}
return cnt;
}
size_t strlen(const char *s){
assert(s!=NULL); //if(s==NULL){return -1;}
size_t cnt = 0;
while(*s++ != '\0'){ //指针表示
++cnt;
}
return cnt;
}
- 字符串拷贝函数:
strcpy(s,s1)
:把s1中的字符拷贝到s里面去,并返回了s字符串的首地址,要保证s足够长> ‘\0’
char *mystrcpy(char *dest,const char *src){ //指针
assert(dest!=NULL&&src!=NULL);
char *pdest = dest;
while( (*dest++ = *src++) != '\0'); //*dest = *src != '\0' ++
return pdest;
}
char *mystrcpy(char *dest,const char *src){ //数组
assert(dest!=NULL&&src!=NULL);
int i = 0;
for(;src[i]!='\0';i++){
dest[i] = src[i];
}
dest[i] = '\0';
return dest;
}
strncpy(s,s1,n)
:把s1中的n个字符拷贝到s里面去,并返回了s字符串的首地址
char *mystrncpy(char *dest,const char *src,size_t n){ //数组
assert(des!=NULL&&src!=NULL);
char *pdest = dest;
int i = 0 ;
for(;i<n;i++){
dest[i] = src[i];
if(src[i] = '\0'){
bresk;
}
}
return dest;
}
char *mystrncpy(char *dest,const char *src,size_t n){ //指针
assert(des!=NULL&&src!=NULL);
char *pdest = dest;
while(n-- >0 && (*dest++ = *src++) != '\0');
return pdest;
}
- 字符串追加函数
strcat :
char *mystrcat(char *dest,const char *src){ //数组表示
assert(des!=NULL&&src!=NULL);
size_t len = strlen(dest);
size_t i;
for(i=0;src[i]!='\0';i++){
dest[len+i] = src[i];
}
dest[len+i] = '\0';
return dest;
}
char *mystrcat(char *dest,const char *src){ //指针表示
assert(des!=NULL&&src!=NULL);
char *pdest = dest;
while(*dest != '\0'){
++dest;
}
while((*dest++ = *src++) != '\0');
return pdest;
}
strncat:
char *mystrncat(char *dest,const char *src,size_t n){
assert(des!=NULL&&src!=NULL);
size_t len = strlen(dest);
size_t i;
for(i=0;i<n && src[i]!='\0';i++){
dest[len+i] = src[i];
}
dest[len+i] = '\0';
return dest;
}
char *mystrncat(char *dest,const char *src,size_t n){
assert(des!=NULL&&src!=NULL);
char *pdest = dest;
while(*dest != '\0'){
++dest;
}
while(n-- > 0 &&(*dest++ = *src++) != '\0');
*dest = '\0';
return pdest;
}
- 字符串比较函数
strcmp(s1,s2)
: =0: s1 == s2 >0 : s1 > s2 <0 : s1 < s2
int *strcmp(const char *s1,const char *s2){
assert(s1!=NULL&&s2!=NULL);
while(*s1!='\0' && *s2!='\0' && *s1==*s2){
++s1;
++s2;
}
return *s1 - *s2;
}
int *strcmp(const char *s1,const char *s2){
assert(s1!=NULL&&s2!=NULL);
size_t i=0;
while(s1[i]!='\0' && s2[i]!='\0' && s1[i]==s2[i]){
++i;
}
return s1[i] - s2[i];
}
strncmp(s1,s2,n)
: 比较前面n个字符, =0 : s1 == s2 >0 : s1 > s2 <0 : s1 < s2
int *strncmp(const char *s1,const char *s2,size_t n){
assert(s1!=NULL&&s2!=NULL);
while(n>0 && s1[i]!='\0' && s2[i]!='\0' && s1[i]==*s2){
++s1;
++s2;
--n;
}
return *s1 - *s2;
}
int *strncmp(const char *s1,const char *s2,size_t n){
assert(s1!=NULL&&s2!=NULL);
size_t i=0;
while(i=0;i<n && s1[i]!='\0' && s2[i]!='\0' && s1[i]==s2[i];i++);
return s1[i] - s2[i];
}
字符串读取:
scanf("%s",str); //读取字符串遇到空白字符结束
char *gets(char *s); //在11标准中已经删除
//非常危险,没有长度限制,没有考虑数组越界问题,遇到换行结束
char *fgets(char *s,int size,FILE *stream); //建议使用 最后会确保一定有一个'\0'
//FILE * stream: stdin 标准输入
//如果字符个数小于size,那么'\n'也一并读入进去
stdin:标准输入
stdout:标准输出
stderr:标准错误输出
int scanf(const char *format, ...);//标准格式输入
int sscanf(const char *str, const char *format, ...);//字符串格式输入,到str中格式读取数据
int printf(const char *format, ...);
int sprintf(char *str, const char *format, ...);
字符串也是C语言中的重要内容之一,字符串操作也是必须要掌握的知识点,不但要学会直接调用,还要能够自己写出来,在不调用系统函数的情况下实现字符串操作。