字符串
字符串就是一系列字符的集合,在C语言中没有像C++中那样专门的字符串类型string,字符串实际上就是一个字符数组
字符数组初始化
字符数组可以用字符串字面值对字符数组进行初始化,也可以用列表进行初始化
字符数组用列表初始化时,没有空字符;用字符串字面值初始化时,结尾有空字符
#include <stdio.h>
int main(){
char a[] = "Hello";
char b[] = {'H','e','l','l','o'};
printf("字符串字面值初始化:a = %s,sizeof(a) = %zd\n", a,sizeof(a));
printf("列表初始化:b = %s,sizeof(b) = %zd\n", a,sizeof(b));
return 0;
}
字符串结束标志
在C语言中,字符串总是以’\0’作为结尾,’\0’也称为字符串结束标记或字符串结束符
C语言处理字符串时,会逐个对字符串中的每个字符进行检查,一旦遇到’\0’就认为到达字符串结尾,才结束处理
#include <stdio.h>
int main(){
char str[30];
char str2[30]={'\0'};
char c;
int i;
for(c=65,i=0; c<=90; c++,i++){
str[i] = c;
str2[i] = c;
}
printf("未初始化:%s\n", str);
printf("初始化为:%s\n", str2);
return 0;
}
字符串处理函数
在C标准库中,头文件中cstring(string.h)定了很多字符串处理函数
- cstring:是新标准规定的名称
- string.h:是旧标准定义的名称
字符串处理函数根据功能可以分为:复制字符串函数、连接字符串函数、比较字符串函数以及其他计算大小,切割字符串函数
strcpy
函数原型:char * strcpy ( char * destination, const char * source );
功能
将源指向的C字符串复制到目标指向的数组中,包括终止空字符(并在此点停止)。为了避免溢出,destination指向的数组的大小应该足够长,以包含与source相同的C字符串(包括结束的null字符),并且不应该在内存中与source重叠
参数
destination:指向要复制内容的目标数组的指针
source:要复制的C字符串
返回值
指向要复制内容的目标数组的指针
用法
#include <stdio.h>
#include <string.h>
int main(){
char str1[] = "hello,world";
char str2[12];
char str3[20];
strcpy(str2,str1);
strcpy(str3,"niceBeautiful");
printf(" str2:%s\n sizeof(str2):%zd\n strlen(str2):%zd\n",str2,sizeof(str2),strlen(str2));
printf(" str3:%s\n sizeof(str3):%zd\n strlen(str3):%zd\n",str3,sizeof(str3),strlen(str3));
return 0;
}
手动实现strcpy
#include <stdio.h>
#include <assert.h>
#include <string.h>
char* my_strcpy(char* dst,const char* src)
{
assert(dst != NULL && src != NULL);
char* ret = dst;
while((*dst++ = *src++) !='\0');
return ret;
}
int main()
{
char a[] = "hell";
char b[] = "hell0,world";
char* my = my_strcpy(b,a);
printf("%s\n", my);
printf("strlen(my):%d\n",strlen(my_strcpy(b,a)));
return 0;
}
strcpy解析
1、返回类型为char*类型目的:为了可以使用链式表达式:即strlen(my_strcpy(b,a))
2、char* dest字符串长度必须要长于要复制的字符串char* src
3、将src字符串的每个字符(包括字符串结束字符)复制给dest
4、返回指向目标字符数组的指针ret,ret找到一个字符串结束标记’\0’就结束,而不是返回dest,因为此时dest已经偏移至src结束字符的下一个位置
5、strcpy没有进行安全性检查dest大小是否满足要求,所以需要程序员自己确认数组大小是否满足复制之后的大小要求
strcat
函数原型:char * strcat ( char * destination, const char * source );
功能
将源字符串的副本追加到目标字符串。destination中的结束空字符被source中的第一个字符覆盖,并且在由destination中的两个字符串联形成的新字符串的末尾包含一个空字符。目标和源不应重叠
参数
destination:指向目标数组的指针,该数组应该包含一个C字符串,并且要足够大,以包含连接的结果字符串
source:要附加的C字符串。这应该不会与目的地重叠
返回值
指向要复制内容的目标数组的指针
用法
#include <stdio.h>
#include <string.h>
int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}
手动实现strcat
#include <stdio.h>
#include <assert.h>
#include <string.h>
char* my_strcat(char* dest,const char* src)
{
assert(dest!=NULL && src!=NULL);
char* ret = dest;
while((*dest) != '\0')
{
dest++;
}
while((*dest++ = *src++) != '\0');
return ret;
}
int main()
{
char a[20] = "hello,";
char b[] = "world";
char* ret = my_strcat(a,b);
printf("%s",ret);
return 0;
}
strcat解析
1、与strcpy相比较就等同于将dest的字符串结束标记去掉然后再将src整个字符串复制给dest
2、返回类型为char*类型目的:为了可以使用链式表达式:即strlen(my_strcat(b,a))
3、dest的字符数组大小应当足够大能够容纳两个字符串连接之后的大小
4、strcat同strcpy一样没有对dest目标字符串进行安全检查,所以程序员自己应确认dest大小是否满足连接之后的大小要求
5、dest指针偏移至结束符前一个位置,然后下一个位置将src的字符(包括结束符)一个复制过来,返回ret,而不是dest,此时dest偏移至src字符串结束符 下一个位置
strcmp
函数原型:int strcmp ( const char * str1, const char * str2 );
功能
比较两个字符串,从两个字符串开始的第一个字符进行比较,如果相等则进行下一个字符的比较,直到字符不相等或者出现一个终止的空字符为止
strcmp比较字符串所有字符是按照机器排序序列进行比较,即根据字符数值进行比较(通常是ASCII值)
参数
两个比较的字符串参数
返回值
返回一个整数值,表示两个字符串比较的结果关系
- 返回值小于0,第一个不匹配的字符在ptr1中的值比在ptr2中的值低
- 返回值等于0,两个字符串的内容相等
- 返回值大于0,第一个不匹配的字符在ptr1中的值大于ptr2中的值
用法
#include <stdio.h>
#include <string.h>
int main ()
{
char key[] = "apple";
char buffer[80];
do {
printf ("Guess my favorite fruit? ");
fflush (stdout);
scanf ("%79s",buffer);
} while (strcmp (key,buffer) != 0);
puts ("Correct answer!");
return 0;
}
手动实现strcmp
#include <stdio.h>
#include <assert.h>
#include <string.h>
int my_strcmp(const char *str1,const char *str2)
{
assert(str1!=NULL && str2!=NULL);
while(*str1 && *str2 && (*str1 == *str2))
{
str1++;
str2++;
}
return *str1-*str2;
}
int my_strcmp2(const char* str1,const char* str2)
{
assert(str1!=NULL && str2!=NULL);
for(int i=0;str1[i]!='\0',str2[i]!='\0';i++)
{
if(str2[i] == str1[i])
{
continue;
return 0;
}else{
return str2[i] - str1[i];
}
}
}
int main ()
{
char a[] = "hallb";
char b[] = "hallb";
int num = my_strcmp(a,b);
int num2 = my_strcmp2(a,b);
printf("my_strcmp;%d\n",num);
printf("my_strcmp2;%d",num2);
return 0;
}
strlen
函数原型:size_t strlen ( const char * str );
功能
获取字符串长度返回C字符串str的长度。C字符串的长度由结束空字符决定:C字符串的长度等于字符串开头和结束空字符之间的字符数(不包括结束空字符本身)
参数
C字符串
返回值
size_t类型,是计算机相关的无符号类型,被设计成足够大以满足内存中任何对象的大小
用法
#include <stdio.h>
#include <string.h>
int main ()
{
char str[256] = "kiliopwewrd";
printf ("(unsigned)strlen(szInput)=%zd\n",strlen(str));
return 0;
}
手动实现
#include <stdio.h>
#include <assert.h>
size_t my_strlen(const char* str)
{
assert(str!=NULL);
int count = 0;
while(*str != '\0')
{
str++;
count++;
}
return count;
}
int main()
{
char a[] = "helloworld";
size_t num = my_strlen(a);
printf("%zd",num);
}
总结
C语言中,字符串就是字符数组的表达方式,字符数组用字符串字面值初始化时,结尾会有空字符’\0’,当用列表初始化时,结尾不会有空字符。C标准库中的string.h头文件中定义了很多字符串的处理函数,学习了最常用的C字符串函数,并尝试手动实现了其功能
赶紧学习起来吧!我是一个正在努力找回自我的人,希望能和一起学习的人成长,有错误的地方请各位大佬帮忙指正,如果觉得有帮助就点个赞当作对我的一个小肯定?,peace&love
|