C语言中的字符串

一、什么是字符串?

在 C 语言中,字符串实际上是使用空字符 \0 结尾的一维字符数组。因此,\0 是用于标记字符串的结束。

空字符(Null character)又称结束符,缩写 NULL,是一个数值为 0 的控制字符,\0 是转义字符,意思是告诉编译器,这不是字符 0,而是空字符。

二、字符串的输入和输出

#include <stdio.h>
int main()
{
    //字符串的定义
    char cdata1[] = "I am a student";
    char cdata2[15] = {'I','\0','a','m','\0','a','\0','s','t','u','d','e','n','t','\0'};
    char *p = "I am a student"//字符串常量,不允许被修改
    /*字符数组的输入输出可以有两种方法。
    (1)逐个字符输入输出。用格式符“%c”输入或输出一个字符
    (2)将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串(string)的输入输出*/
    for(int i=0;i<15;i++){
        printf("%c",cdata2[i]);
    }
    printf("\n%s",cdata1);
    printf("\n%s",cdata2);//用%s输出cdata2,遇到空字符会提前结束打印
    return 0;
}
/*运行结果
I am a student
I am a student
I*/

三、处理字符串的常见函数

1、puts函数

输出字符串的函数

一般形式 puts(str);
str -- 这是要被写入的C字符串。
自带换行符,其作用是将一个字符串(以'\0'结束的字符序列)输出到终端。

2、gets函数

输入字符串的函数

一般形式 gets(str);
str -- 这是指向一个字符数组的指针,该数组存储了C字符串。
其作用是从终端输入一个字符串到字符数组,并且得到一个函数值。该函数值是字符数组的起始地址。

3、strcat函数

字符串连接函数

一般形式 strcat(str1,str2);
其作用是把两个字符串连接起来:
将字符串str2连到字符串str1后面。函数调用后得到字符串str1的地址。

函数原型 char *strcat(char *dest, const char *src);
dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
src -- 指向要追加的字符串,该字符串不会覆盖目标字符串。

//strcat函数使用方法
#include <stdio.h>
#include <string.h>
#include <assert.h>//assert的头文件
int main()
{
    //char *strcat(char *dest, const char *src);函数原型
    char str1[] = "Changcheng";
    char str2[] = " Pao!";
    strcat(str1,str2);
    printf("%s",str1);
    return 0;
}
/*运行结果:
Changcheng Pao!*/
​
//strcat的函数实现
char *myStrcat(char*dest,const char *src)
{
    if(dest == NULL && src == NULL){//先判断两个字符串是否为空
        return NULL;
    }
    char *bak = dest;//先将dest的地址备份
    while(*dest != '\0'){//定位到dest的末尾
        dest++;
    }
    while(*dest++ = *src++);//将src的内容复制到dest的末尾
    *dest = '\0';//字符串以'\0'为结尾
    return bak;//将dest原地址返回
}
​
char *myStrcat2(char*dest,const char *src)
{
    assert(dest != NULL && src != NULL);//断言函数,如果为空函数则终止程序运行
    
    char *bak = dest;//先将dest的地址备份
    for(;*dest!='\0';dest++);//定位到dest的末尾
    while(*dest++ = *src++);//将src的内容复制到dest的末尾
    *dest = '\0';//字符串以'\0'为结尾
    return bak;//将dest原地址返回
}

4、strcpy 和 strncpy函数

字符串复制函数

strcpy的一般形式 strcpy(str1,str2);
其作用是将字符串str2复制到字符串str1中

函数原型 char *strcpy(char *dest, const char *src)
dest -- 指向用于存储复制内容的目标数组。
src -- 要复制的字符串。

strncpy的一般形式 strncpy(str1,str2,n); 其作用是将字符串str2的前n个字符串复制到字符串str1中,当 str2的长度小于 n 时,str1的剩余部分将用空字节填充。

函数原型 char *strncpy(char *dest, const char *src, size_t n);
dest -- 指向用于存储复制内容的目标数组。
src -- 要复制的字符串。
n -- 要从源中复制的字符数。

//strcpy函数使用方法
#include <stdio.h>
#include <string.h>
#include <assert.h>//assert的头文件
int main()
{
    char str1[12];
    char str2[12];
    char *p = "Sun Wukong";
    strcpy(str1,p);//将p的值复制给str1
    strncpy(str2,p,3);//将p的前三个值复制给str2
    printf("str1的值是%s\n",str1);
    printf("str2的值是%s\n",str2);
    return 0;
}
/*运行结果:
str1的值是Sun Wukong
str2的值是Sun*/
​
//strcpy的函数实现
char *myStrcpy(char *dest, const char *src)
{
    assert(dest!=NULL && src != NULL);//断言函数,如果两个字符串都为空,直接退出程序
    char *bak = dest;
    
    while(*src != '\0'){//将src空字符之前的数据复制给dest
        *dest = *src;
        *dest++;
        *src++;
    }
    *dest = '\0';//字符串以'\0'为结尾
    return bak;
}
​
char *myStrcpy2(char *dest, const char *src)
{
    assert(dest!=NULL && src != NULL);//断言函数,如果两个字符串都为空,直接退出程序
    char *bak = dest;
    
    while(*src != '\0'){
        *dest++ = *src++;
    }
    *dest = '\0';
    return bak;
}
​
char *myStrcpy3(char *dest, const char *src)
{
    assert(dest!=NULL && src != NULL);//断言函数,如果两个字符串都为空,直接退出程序
    char *bak = dest;
    
    while((*dest++ = *src++) != '\0');
    *dest = '\0';
    return bak;
}
​
//strncpy的函数实现
char *myStrncpy(char *dest, const char *src, size_t n)
{
    assert(dest!=NULL && src != NULL);//断言函数,如果两个字符串都为空,直接退出程序
    char *bak = dest;
    
    while(*src != '\0' && n>0){//将src的前n个字符复制给dest
        *dest++ = *src++;
        n--;
    }
    *dest = '\0';
    if(n>0){//src的长度小于n时,将src全部复制到dest中,n剩下的值全部赋0\给dest;
        n--;
        *dest = '\0';
    }
    return bak;
}

5、strcmp函数

字符串比较函数

一般形式 strcmp(str1,str2) 其作用为将字符串str1和str2比较

函数原型 int strncmp(const char *str1, const char *str2)
str1 -- 要进行比较的第一个字符串。
str2 -- 要进行比较的第二个字符串。

字符串比较的规则是:将两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到'0'为止。
(1)如全部字符相同,则认为两个字符串相等;
(2)若出现不相同的字符,则以第1对不相同的字符的比较结果为准。例如:

"A"<"B" ,"a">"A","computer">"compare" ,"these">"that", "1A">"$20","CHINA">"CANADA","DOG"<"cat","Tsinghua">"TSINGHUA"

比较的结果由函数值带回:
(1)如果字符串str1=字符串str2,则函数值为0。
(2)如果字符串str1>字符串str2,则函数值为一个正整数。
(3)如果字符串str1<字符串str2,则函数值为一个负整数。

//strcmp函数使用方法
#include <stdio.h>
#include <string.h>
#include <assert.h>//assert的头文件
int main()
{
    int a;
    int b;
    int c;
    char str1[] = "app";
    char str2[] = "app";
    a = strcmp(str1,str2);
    
    char str3[] = "hallo";
    char str4[] = "hello";
    b = strcmp(str3,str4);//a<e
​
    char str5[] = "Dog";
    char str6[] = "Dod";
    c = strcmp(str3,str4);//g>d
    
    printf("%d  ",a);
    printf("%d  ",b);
    printf("%d  ",c);
}
/*运行结果
0   -1   1*/
//strcmp的函数实现
int myStrncmp(const char *str1, const char *str2)
{
    int ret;
    assert(str1!=NULL && str2 != NULL);//断言函数,如果两个字符串都为空,直接退出程序
    
    while(*str1 && *str2 && (*str1 == *str2)){
        str1++;
        str2++;
    }
    ret = *str1 - *str2;
    if(ret>0){
        ret = 1;
    }
    if(ret<0){
        ret = -1;
    }
    return ret;
}
​
//strcmp只能比较当字符串出现第一个字符不相等时的字符大小
//如果想完全比较两个字符串的大小可以将两个字符串的ASCII码全部加起来之后再比较
int myStrncmp(const char *str1, const char *str2)
{
    int ret;
    int cnt1 = 0;
    int cnt2 = 0;
    assert(str1!=NULL && str2 != NULL);//断言函数,如果两个字符串都为空,直接退出程序
​
    while(*str1 && *str2 && (*str1 == *str2)){
        str1++;
        str2++;
    }//先让两个字符串相等或者不为0的地址向后偏移
    while(*str1){
        cnt1 = cnt1 + *str1;
        str1++;
    }
    while(*str2){
        cnt2 = cnt2 + *str2;
        str2++;
    }
​
    ret = cnt1 - cnt2;
    if(ret>0){
        ret = 1;
    }
    if(ret<0){
        ret = -1;
    }
    return ret;
}

6、strstr函数

定位子字符串的函数

一般形式 strstr(str1,str2)
在str1中找str2出现的位置,返回str2的字符串在str1字符串第一次出现的位置,不包含终止符 '\0'。如果没有找到或者str2不是str1的一部分,则返回null指针。

函数原型 char *strstr(const char *haystack, const char *needle);
haystack -- 要被检索的 C 字符串。
needle -- 在 haystack 字符串内要搜索的小字符串。

//strstr函数使用方法
#include <stdio.h>
#include <string.h>
#include <assert.h>//assert的头文件
int main()
{
    char str1[] = "hello word!";
    char str2[] = "wo";
    char* ret = strstr(str1,str2);
    if (ret == NULL)
        printf("找不到!\n");
    else
        printf("%s\n", ret);
    return 0;
}
/*运行结果
  word!*/
​
//strstr函数实现
 char *myStrstr( char *str1,  char *str2)
 {
     assert(str1!=NULL && str2 != NULL);//断言,先处理空字符
     char *s1 = str1;//遍历指向str1的字符串
     char *s2 = str2;//遍历指向str2的字符串
     char *p;
     p = str1;//记录开始遍历的位置
     while(*p){
         s1 = p;//让s1指向p偏移的位置
         s2 = str2;//让s2重新指向第一个字符位置
        while(*s1 && *s2 && (*s1 == *s2)){//遍历str1和str2相等的字符
            s1++;
            s2++;
        }
        if(*s2 == '\0'){//如果找到str2所有的字符,返回该位置的指针
            return p;
        }
        p++;
     }
        return NULL;
 }

7、strlen函数和sizeof关键字

sizeof() 和 strlen() 在 C 语言中两个非常常用,它们都与计算内存大小有关,但是它们的作用是不同的。

1、strlen:这个函数用于计算字符串(char数组)中字符的数量,不包括结束符'\0'。它返回的是一个整数,表示实际字符的数量。

2、sizeof:这是一个运算符,用于获取数据类型或变量在内存中占用的字节数。它可以用于任何数据类型,如基本类型、结构体、数组等,返回的是一个整数。

sizeof() 和 strlen() 的主要区别在于:

  • sizeof() 是一个关键字、运算符,而 strlen() 是一个函数。

  • sizeof() 计算的是变量或类型所占用的内存字节数,而 strlen() 计算的是字符串中字符的个数。

  • sizeof() 可以用于任何类型的数据,而 strlen() 只能用于以空字符 '\0' 结尾的字符串。

  • sizeof() 计算字符串的长度,包含末尾的 '\0',strlen() 计算字符串的长度,不包含字符串末尾的 '\0'。

总结来说:

sizeof关心的是内存占用空间的大小,计算的是实际长度

strlen关注的是字符数组的内容长度,计算的是有效长度

int main()
{
    //sizeof和strlen的区别
    //sizeof计算的是数组的实际长度,strlen计算的是数组的有效长度
    char cdata[128] = "hello";
    void (*ptest)();
    ptest = test;
    
    printf("sizeof:%d\n",sizeof(cdata));//sizeof计算得出cdata[]的大小是 128
    printf("strlen:%d\n",strlen(cdata));//strlen计算得出cdata[]的大小是 5
    
    char *p = "hello";
    //*p是一个char *,sizeof来计算的时候,得出的是计算机用多少字节表示一个地址
    
    printf("sizeof:p       %d\n",sizeof(p));     //sizeof  8
    printf("strlen:p       %d\n",strlen(p));     //strlen计算得出p的大小是 5
    printf("sizeof:char *  %d\n",sizeof(char *));//char *的大小是 8
    printf("sizeof:int *   %d\n",sizeof(int *)); //int *的大小是 8
    printf("sizeof:char    %d\n",sizeof(char )); //char 的大小是 1
    printf("sizeof:ptest   %d\n",sizeof(ptest)); //ptest的大小是 8
​
    return 0;
}
    /*运行结果
    sizeof:128
    strlen:5
    sizeof:p       8
    strlen:p       5
    sizeof:char *  8
    sizeof:int *   8
    sizeof:char    1
    sizeof:ptest   8
    */

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值