【C上分之路】第六篇:字符串初始化、字符串函数strcpy、strcat、strcmp

冲鸭

字符串

字符串就是一系列字符的集合,在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用法

手动实现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手动实现

strcpy解析

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用法

手动实现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');
    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手动实现

strcat解析

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值)

参数

两个比较的字符串参数

返回值

返回一个整数值,表示两个字符串比较的结果关系

  1. 返回值小于0,第一个不匹配的字符在ptr1中的值比在ptr2中的值低
  2. 返回值等于0,两个字符串的内容相等
  3. 返回值大于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用法

手动实现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;
}
strcmp手动实现

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;
}
strcat用法

手动实现

#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);
}
strlen手动实现

总结

C语言中,字符串就是字符数组的表达方式,字符数组用字符串字面值初始化时,结尾会有空字符’\0’,当用列表初始化时,结尾不会有空字符。C标准库中的string.h头文件中定义了很多字符串的处理函数,学习了最常用的C字符串函数,并尝试手动实现了其功能

赶紧学习起来吧!我是一个正在努力找回自我的人,希望能和一起学习的人成长,有错误的地方请各位大佬帮忙指正,如果觉得有帮助就点个赞当作对我的一个小肯定❤,peace&love

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值