C语言基础之字符串

发布于:2023-01-26 ⋅ 阅读:(22) ⋅ 点赞:(0) ⋅ 评论:(0)

一、字符的定义方式及输出

1.什么是字符串?

  • 字符串就是字符数组,好多个字符串起来的一组数据。

2.直接看代码,注意自己写的注释

#include<stdio.h>
int main()
{
    int i;
    char c = 'c';//定义了一个字符数据类型c
   //所以,第一种定义字符串数组的方式
    char str[3] = {'a','b','c'};//和整型数组相似
   //访问方式
    for(i-0;i<sizeof(str) / sizeof(str[0]);i++){
        printf("%c ",str[i]);
   }
    putchar('\n');
   
   //第二种定义字符按串数组的方式
    char str2[3] = "abc";//也和整型数组相似
    for(i=0;i<sizeof(str2) / sizeof(str2[0]);i++){
        printf("%c ",str2[i]);
   }
    putchar('\n');
   
   //第三种定义字符串的方式
    char str3[] = "abc";//数组元素个数不写,会根据真实大小来默认分配
    for(i=0;i<sizeof(str3) / sizeof)(str3[0]);i++){
       printf("%c ",str3[i]);
   }
    putchar('\n');

   //第四种定义字符串数组的方式
    char *pstr = "i am handsome";//指针方式,如果操作不恰当,内存非法,易造成段错误
    printf("%s",pstr);//字符串用格式占位符%s表示,不需要用i的下标遍历
    putchar('\n');
    return 0;
}

3.运行结果:
在这里插入图片描述

二、字符串在内存中的存储方式

1.下面用代码类比

#include<stdio.h>
int main()
{
    int a[3] = {1,2,3};//连续的空间,整个数组的大小是:元素的个数*元素类型的大小
    printf("a数组的大小是:%ld\n",sizeof(a));
    printf("数组元素的大小是:%ld\n",sizeof(a[0]));
    printf("数组元素大小是:%ld\n",sizeof(int));
    printf("数组的个数可以这么算:%ld\n",sizeof(a)/sizeof(a[0]));
    puchar('\n');
     
    char a2[3] = {'a','b','c'};
    printf("a2数组的大小是:%ld\n",sizeof(a2));
    printf("数组元素的大小是:%ld\n",sizeof(a2[0]));
    printf("数组元素大小是:%ld\n",sizeof(char));
    printf("数组的个数可以这么算:%ld\n",sizeof(a2)/sizeof(a2[0]));
    puchar('\n');
    
    char a3[3] = "abc";
    printf("a3数组的大小是:%ld\n",sizeof(a3));
    printf("数组元素的大小是:%ld\n",sizeof(a3[0]));
    printf("数组元素大小是:%ld\n",sizeof(char));
    printf("数组的个数可以这么算:%ld\n",sizeof(a3)/sizeof(a3[0]));
    puchar('\n');
    
    //中括号不写数组的大小,上面说了会根据初始化的时候元素个数来确定
    char a4[] = "abc";
    printf("a4数组的大小是:%ld\n",sizeof(a4));
    printf("数组元素的大小是:%ld\n",sizeof(a4[0]));
    printf("数组元素大小是:%ld\n",sizeof(char));
    printf("数组的个数可以这么算:%ld\n",sizeof(a4)/sizeof(a4[0]));

    return 0;
}

2.看运行结果:
在这里插入图片描述
3.注意看a4数组的大小,为什么是4而不是3?

是因为字符串在内存中,除了有效字符abc以外,还会自动在后面补上一个 \0 ,作为字符串的结束标志

三、strlen来计算字符串中字符个数

不能用sizeof来计算字符串中有效字符的个数!!!应该要用strlen,它在计算字符串大小的时候,遇到 ‘\0’ 后,就结束计数!

四、字符串操作常用函数

1.printf和puts函数都是输出字符串,scanf和get函数都是输入字符串,以及初始化函数memset的使用

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char *str = "i am handsome";
    printf("%s ",str);
    putchar('\n');
    puts(str);
    putchar('\n');
    
    //野指针,造成非法内存,出现段错误
    char *pstr;
    pstr = (char *)malloc(128);//1.申请了空间
    memset(pstr,'\0',128);//2.初始化,把每个元素都初始化为'\0'
    if(pstr == NULL){
       printf("开辟空间失败!\n");
       exit(-1);
    }
    //对应的参数:1.初始化的对象 2.初始化成什么字符 3.初始化的大小
    printf("请输入字符串:\n");
    //scanf("%s",pstr);
    gets(pstr);
    puts(pstr);
    
    return 0;
}

2.看运行结果:
在这里插入图片描述
3.注意:

  • 一旦用malloc申请了空间,一定要注意内存泄漏的问题
  • malloc可能会开辟失败,要对返回值做判断

2.拷贝函数strcpy和strncpy,拼接strcat和比较strcmp

1.看代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
    //拷贝原型:char *strcpy(char *dest, const char *src);
    char *strDest;
    strDest = (char *)malloc(128);
    memset(strDest,'\0',128);  

    char *strSrc = "iam handsome";
    strcpy(strDest,strSrc);
    puts(strDest);
    putchar('\n');
    
    //拷贝原型:char *strncpy(char *dest, const char *src, size_t n);
    memset(strDest,'\0',128);
    strncpy(strDest,strSrc,3);//相比strcpy多了一个拷贝长度的参数
    puts(strDest);
    putchar('\n');
    
    // 拼接原型:char *strcat(char *dest, const char *src);
    char text[128] = "yes";
    strcat(text,strSrc);
    puts(text);
    putchar('\n');

    //比较原型:int strcmp(const char *s1, const char *s2);
    char *str1 = "123";
    char *str2 = "1234";
    int ret = strcmp(str1,str2);
    printf("%d\n",ret);
    
    return 0;
}

2.看运行结果:
在这里插入图片描述

  • 注意:比较strcmp,他返回的是一个整数,如果第一个参数大于第二个参数,那么返回的就是正数,反之返回的是负数。诺两个比较的参数相等,则返回的是0

3.查找子字符strchr和查子串strstr,转为小写的函数strlwr和转为大写的函数strupr

1.看代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
    //查找子字符原型:char *strchr(const char *s, int c);
    char *str = "iamhandsome";
    char c = 'h';
    char *p = NULL;
    p = strchr(str,c);
    if(p == NULL){
       printf("没找到!\n");
    }else{
       printf("找到了!\n");
       puts(p);
     }
    putchar('\n');

    //查找子串原型:char *strstr(const char *haystack, const char *needle);
    char *substr = "am";
    p = strstr(str,substr);
    if(p == NULL){
       printf("没找到!\n");
    }else{
       printf("找到了!\n");
       puts(p);
     }
    putchar('\n');

    // 转为小写的函数原型:char *strlwr(char *str)
    char *str1 = "I am Handsome";
    puts(strlwr(str1));
    puts(strupr(str1));
    return 0;
}

2.看运行结果:
在这里插入图片描述

4.字符串分割strtok

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
    //原型:char *strtok(char *str, const char *delim);
      char str[] = "i,am,hand,some";
      char *psubs[10];
      int i = 1;
      char *p = NULL;

      p = strtok(str,",");//第一次分割,返回的是第一次找到逗号前面的字符串!
      if(p != NULL){
         psubs[i-1] = p;
      }
      while(1){
               i++;
               p = strtok(NULL,",");//第二次分割,必须还得使用该函数,注意第一个参数为NULL
               if(p != NULL){
                  psubs[i-1] = p;
               }else{
                  printf("没有子串了!\n");
                  break;
               }
      }
      int j;
      for(j=0;j<i;j++){
          puts(psubs[j]);
      }
      system("pause");
    return 0;
}

运行结果:
在这里插入图片描述

五、自己实现字符串api

1.通过函数来自己实现字符串的api,puts输出和puts输入函数:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void myputs(char *p)//自己实现输出api
{
        while(*p != '\0'){
                putchar(*p++);
        }
        putchar('\n');
}

void mygets(char *p)//自己实现输入api
{
        if(p == NULL){
                printf("内存非法!\n");
                return;
        }
        while(*p = getchar()){
                if(*p == '\n'){
                        return;
                }else{
                        p++;
                }
        }
}
int main()
{
        char str[128] = {'\0'};
        char *p = "i am handsome";
        myputs(p);

        myputs("请输入你的字符串");
        mygets(str);
        myputs(str);

        return 0;
}


2.看运行结果:
在这里插入图片描述

2.自己实现计算长度strlen和初始化memset

1.看代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int mystrlen(char *p)
{
    int cnt = 0;
    while(*p++ != '\0'){
          cnt++;
    }
    return cnt;
}
void mymemset(char *p,char c,int size)
{
     while(size){
           *p++ = c;
            size--;
     }
}
int main()
{
    char *str = "i am handsome";
    printf("字符串长度是:%d\n",mystrlen(str));
    
    char *str2 = NULL;
    str2 = (char *)malloc(6);
    mymemset(str2,'v',6);
    str2[6] = '\0';
    puts(str2);
}

2.运行结果:
在这里插入图片描述

3.自己实现字符串拷贝strcpy和strncpy,

1:代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *mystrcpy(char *dest, const char *src)
{
      if(dest == NULL || src == NULL){
          return NULL;
      }
      while(*src != '\0'){
            *dest++ = *src++;
            }
            *dest = '\0';
            return dest;
}
char *mystrncpy(char *dest, const char *src,int n)
{
      if(dest == NULL || src == NULL){
          return NULL;
      }
      while(*src != '\0' && n>0){
            *dest++ = *src++;
             n--;
            }
            *dest = '\0';
            return dest;
}
int main()
{
    char *str = "i am handsome";
    char *dest;
    dest = (char *)malloc(128);
    memset(dest,'\0',128);
    mystrcpy(dest,str);
    puts(dest);
    mystrncpy(dest,str,2);
    puts(dest);
    return 0;
}

2.运行结果:
在这里插入图片描述

4.自己实现字符串的拼接strcat

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void mystrcat(char *dest,char *src)
{
     while(*dest != '\0'){
         dest++;
     }
     while(*src != '\0'){
            *dest++ = *src++;
     }
     *dest = '\0';
}
int main()
{
    char dest[128] = "yes ";
    char *src = "i am handsome";
    mystrcat(dest,src);
    puts(dest);
    system("pause");
    return 0;
}

看运行结果:
在这里插入图片描述


网站公告

欢迎关注微信公众号

今日签到

点亮在社区的每一天
签到