C语言中的字符串和字符串函数

  • C语言中的字符串以'\0'或者说是整数0作为结尾的一串字符
    • 0和'\0'是一样的,但是和'0'不同,后者是ASCII码的字符0
  • 0标志字符串的结束,但它不是字符串的一部分
    • 计算字符串的长度时,不包括这个0
  • 字符串以字符数组的形式存在,以数组或者指针的形式访问
    • 不可以用运算符对字符串做运算
    • 一般可以通过数组的方式遍历字符串
  • 字符串变量的多种表现形式
    • char *str ="Hello";//以指针的形式表现字符串变量
    • char word[] ="Hello";//以字符数组的形式
    • char line[10] ="Hello";//表示创建了一个大小为10的字符数组,在数组中放入字符串"Hello"和一个'0'
  • 两个相邻的字符串常量通常会被自动连接起来
    • printf("你好&&"  "谢谢");----->你好&&谢谢
  • C语言中可以通过字符串字面量来初始化字符串数组
    • char *str ="Hello";
  • 字符串常量
    • char *s="Hello World!";
      • s是一个指针,他指向了字符串常量,也就是这个字符串常量所在的地址
      • 对于*s这种指针的写法,C语言中将字符串"Hello World!"存在了代码段
        • 这个位置是只能读,不能写的,如果试图对s所指的字符串修改,将会出现错误
        • 这种写法,更准确的说是 const char *s="Hello World!",但是编译器一般会接受没有const的写法
    • char s[]="Hello World!";
      • 如果想要在后续修改字符串,则应该用数组的方式定义
      • s是一个数组名,它本身就是一个地址,表示说这个字符串就在这个地址这里
        • 指针s都是地址,但是区别在于计算机对于这两个地址的分配方式不同
        • 数组s是和程序里的其他普通变量(例如int i=3;)放在一起的,是本地变量
          • s代表了这个数组首元素的地址
    • 该用哪个呢?
      • 数组:这个字符串就在这里(如果要构造一个字符串----->用数组)
        • 可以更改
        • 作为局部变量会被自动回收
      • 指针:不知道字符串存在哪里(如果要处理一个字符串---->用指针)
        • 处理参数
        • 动态分配空间
    • char*是字符串吗?
      • 字符串可以表达为char*的形式
      • 但char*不一定是字符串
        • char*仅仅是一个指向char的指针,指向的可能还是单个字符、一个char型数组
        • 只有char*指向的是一个结尾为0的字符数组时,char*所指向的才是一个字符串
  • 字符串的输入输出
    • 字符串的赋值问题
      • char *t = "title";
      • char *s;
      • s=t;//并没有产生新的字符串,只是让指针s指向了t所指的字符串,对s的任何操作都是对t做的
    • 字符串的输入输出
      • char string[8];
      • scanf("%s",string);//scanf读入字符的时候读入的是“一个单词”(读到空格、tab、回车为止)
        • 注意:scanf是不安全的,因为不知道要读入的内容的长度
      • printf("%s",string);//打印读入的内容
    • 安全的输入输出
      • 在%和s之间加一个数字,表示最多允许读入的字符的数量,这个数字应该比字符串数组的大小小
        • char string[8];
        • scanf("%7s",string);
      • 下一次的scanf就紧接着上次的结尾继续读入
    • 常见的错误(??)
      • char *string;
      • scanf("%s",string);
        • 以为char*是字符串类型,定义了一个字符串类型的变量string就可以直接使用
        • 由于没对string初始化为0,所以不一定每次运行都出错(为什么要初始化为0?)
    • 空字符串
      • char buffer[100]="";//这是一个空字符串,其中buffer[0]='\0'
      • char buffer[]="";   //这个数组的长度只有1,因此这个字符串数组,什么也放不下
  • 字符串数组
    • char**a是字符串数组吗?
      • 不是:a是一个指针,指向一个指针,被指向的指针指向一个char(或字符串)
        • 注意:字符串是字符数组
    • char a[][n]是字符串数组吗?
      • 不是:a是一个二维数组,或者说是一个指针,a指向拥有n个字符元素的数组
        • 注意:此时如果给a赋值,那么字符串的长度不能超过n-1
    • char *a[]是字符串数组!
      • 这表示a[i]是一个指针,指向一个字符串
      • a[i]就是这个字符串数组中的第i个字符串元素
      • include <stdio.h>
         
        
        int main()
        
        {
        
            int months;
        
            printf("请输入月份:");
        
            scanf("%d", &months);
        
         
        
            char *a[] = {"January", "February", "March", "April", "May", "June", "July", "August","September", "October", "November", "December"};
        
         
        
            printf("%s", a[months - 1]);
        
            return 0;
        
        }

         

  • 程序参数
    • int main(int argu, char const *argv[])
    • argv[0]是命令本身
    • 当使用Unix的符号链接时,反应符号链接的名字
  • 单字符输入输出
    • echo---回声
      • 表示输入什么就会传回来什么
    • putchar:向标准输出写一个字符
      • int putchar(int c);
      • 返回写了几个字符,EOF(-1)表示写失败
        • 正常情况下是返回1,失败的时候返回EOF
    • getchar:从标准输入读一个字符
      • int getchar(void);
      • 返回EOF表示标准输入结束了
      • 在标准输入输出和程序之间有一个程序叫做shell
        • shell的功能是“中间商”
        • 假如需要输入一串字符,在按下回车键之前,数据会被存储在shell的缓冲区
        • 然后按下shell后,这个缓冲区才会开放给程序
          • 如果用getchar,则会一个字符一个字符的读
          • 如果是scanf,则会根据格式化类型读数据
  • 字符串函数---原型包含在string.h头文件中
    • #include<string.h>
    • size_t strlen(const char*s);
      • 返回字符串s的长度(不包括结尾的0)
    • int strcmp(const char*a,const char*b);
      • 返回值是int类型,表示字符串a和b的大小
      • 0:表示字符串相等
      • 1(或者大于0):表示字符串a大于b 
      • -1(或小于0):表示字符串a小于b
        • 字符串a和b的大小如何定义呢?
        • 是从左往右,依次进行单个字符的ASCII码的比较。首先出现差值不为0时,就表示字符串不等
    • char * strcpy(char *restrict dst,const char *restrict src);
      • 把src的字符串拷贝到dst
      • restrict表明src和dst在内存中不可以重叠
      • 返回dst(也就是拷贝完后的字符串)
        • 为了可以让函数的返回值再作为另一个函数的参数等功能
      • 复制一个字符串
        • char *dst=(char*)mallco(strlen(src)+1);//动态申请一块内存,并将返回的指向void类型的指针转化为指向char型的指针
        • strcpy(dst,src);//然后将src的内容复制给dst
    • char *strcat(char *restrict s1,const char *restrict s2);
      • 把s2拷贝到s1后面,紧接成一个长的字符串数组
      • 返回续接后的s1
      • s1必须要有足够的空间
        • 这就产生了一个安全问题---s1的空间有可能是不够的
    • 安全方式的函数
      • char * strncpy(char *restrict dst,const char *restrict srcsize_t n);
        • //表示能够在dst拷贝多少个字符
      • char * strncat(char *restrict s1const char *restrict s2size_t n);
        • //表示能够连在s1后多少个字符
      • int strncmp(const char*a,const char*b,size_t n);
        • //表示会比较前n个字符
    •  在字符串中寻找字符
      • char *strchr(const char *s,int c);
        • //表示在s中寻找字符c,返回从左边算起的第一个找到的自符的指针
      • char *strrchr(const char *s,int c);
        • //表示在s中寻找字符c,返回从右边算起的第一个找到的自符的指针
      • 返回NULL表示没有找到
    • char *strstr(const char *s1, const char *s2);
      • //表示在字符串S1中寻找字符串s2
      • 返回的是被寻找的字符串的第一个字符的地址(指针)
    • char *strcasestr(const char *s1, const char *s2);(不是标准库函数,我的环境里找不到)
      • //功能同上,但不区分大小写
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咖啡与乌龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值