C语言基础(三)——字符串

C语言基础(三)——字符串
  iwehdio的博客园:https://www.cnblogs.com/iwehdio/

导图

1、字符串

  • C语言中的字符串:以 ''0结尾的字符数组。

    • 0或’是一样的,但是和0'不同0标志字符串的结束,但它不是字符串的一部分。
    • 计算字符串长度的时候不包含这个0。
    • 字符串以数组的形式存在,以数组或指针的形式访问。更多的是以指针的形式。
    • string.h 里有很多处理字符串的函数。
  • 字符串常量:以双引号包含的字符串。

    • 会被编译器变成一个字符数组放在某处。

    • 相邻的两个字符串常量会被自动连接起来,不需要加号。

  • C语言的字符串是以字符数组的形态存在的。

    • 不能用运算符对字符串做运算。
    • 通过数组的方式可以遍历字符串。
    • 字符串字面量可以用来初始化字符数组。
  • 字符串变量:

    • 定义字符串变量1:char *s = "Hello,world"
      • s是一个指针,初始化为指向一个字符串常量。
      • 由于这个常量所在的地方是内存中的代码段,只能被读不能被写。所以实际上 s 是 const char*s,但是由于历史的原因,编译器接受不带 const 的写法。
      • 试图对s所指的字符串做写入会导致严重的后果。
    • 定义字符串变量2:char s[] = "Hello,world"
      • 这样做可以修改字符串。
    • 用数组定义字符串:表示这个字符串在这里,程序运行的本地。
      • 作为本地变量空间自动被回收。
    • 用指针定义字符串:这个字符串不知道在哪里,存储在内存中的代码段。
      • 作为函数处理的参数。
      • 动态分配空间时。
  • 如果要构造一个字符串使用数组,如果要处理一个字符串使用指针。

  • 字符串可以表达为 char* 的形式,但 char* 不一定是字符串。

    • 本意是指向字符的指针,可能指向的是字符的数组(就像int*一样)。
    • 只有它所指的字符数组有结尾的 0,才能说它所指的是字符串。
  • 字符串的赋值:

    • char*t="title";char*s;s=t;
    • 并没有产生新的字符串,只是让指针 s 指向了 t 所指的字符串,对 s 的任何操作就是对 t 做的。
  • 字符串的输入输出:

    • 指定格式为 %s 。
    • scanf 读入一个单词,到空格、tab或回车为止(不包含)。
    • scanf 是不安全的,因为不知道要读入的内容的长度。
    • 可以用 %ns 表示 scanf 最多读入 n 个字符。在 % 和 s 之间的数字 n 表示最多允许读入的字符的数量,这个数字应该比数组的大小小一。
    • 常见问题:
      • char* string; scanf("%s",string);
      • 定义了一个字符串类型的变量 string 不能直接使用,需要先初始化为 0。
  • 字符串数组:

    • char **a:代表a是一个指针,指向另一个指针,那个指针指向一个字符(串)。不是字符串数组。
    • char a[][n]:代表数组 a 中的每个元素是有最大长度的字符数组。不是字符串数组。
    • char *a[]:代表数组 a 中的每个元素都指向一个字符数组。是字符串数组。
  • main 函数的程序参数:

    • int main(int argc, char const *argv[])
    • argc 表示传入参数的个数,argv 是在命令行运行程序时按空格分隔的输入的参数。
    • argv[0] 是输入的运行命令本身。

2、字符串函数

  • 先读入库:#include <string.h>

  • putchar:单字符输出:

    • 格式:int putchar(int c)
    • 向标准输出写一个字符。
    • 返回写了几个字符,EOF(-1)表示写失败。
  • getchar:单字符输入。

    • 格式:int getchar(void)
    • 从标准输入读入一个字符。
    • 返回类型是int是为了返回EOF(-1)。
    • 输入结束:
      • Windows-> Ctrl-Z。
      • Unix-> Ctrl-D。
  • strlen:字符串长度。

    • 格式:size_t strlen(const char* s)
    • 返回字符串的长度,不包括结尾的 。也就是比对字符串做 sizeof 少1。
  • strcmp:比较字符串。

    • 格式:int strcmp(const char* s1, const char* s2)

    • s1==s2 时,返回 0;s1>s2 时,返回 1(大于0);s1<s2 时,返回 -1(小于0)。

    • 从前往后逐字符比较,直到比较得到第一个不同的字符(或者第一个字符串到达末尾),返回不同的字符的 ASCII 码值的差。

    • 自己实现 strcmp :

      int mycmp(const char* s1, const char* s2){
          while(*s1 == *s2 && *s1 != ''){
              s1++;
              s2++;
          }
          return *s1 - *s2;
      }
      
  • strcpy:拷贝字符串。

    • 格式:char* strcpy(char* restrict dst, const char* restrict src)

    • 把 src 的字符串拷贝到 dst。

    • restrict 表明 src 和 dst 的内存空间不重叠(C99)。

    • 返回 dst。

    • 复制一个字符串:

      char* dst = (char*)malloc(strlen(src)+1);
      strcpy(dst, src);
      
    • 自己实现 strcpy:

      char* mycpy(char* dst, const char* src){
          char* ret = dst;
          while(*dst++ == *src++ );
          *dst = '';
          return ret;
      }
      
  • strcat:字符串连接。

    • 格式:char* strcat(char* restrict s1,const char* restrict s2)
    • 把 s2 拷贝到 s1 的后面,接成一个长的字符串。
    • 返回s1, s1必须具有足够的空间。
  • 安全问题:

    • 拷贝、连接都可能会出现空间不足的问题。
    • 实际上C也提供了安全版本,传入所需的空间大小。
    • 拷贝n个字符:char *strncpy(char *restrict dst,const char *restrict src,size_tn)
    • 连接n个字符:char * strncat(char *restrict s1,const char *restrict s2,size_tn)
    • 比较前n个字符: strncmp(const char *s1,const char *s2,size_tn)
  • 字符串搜索函数:

    • 从左边开始,寻找字符c第一次出现的位置:char*strchr(const char*s,int c)
    • 从右边开始,寻找字符c第一次出现的位置:char*strrch(const char*s,int c)
    • 返回的是指向找到的 c 的指针,返回NULL表示没有找到。
    • 寻找字符串 s2 第一次出现的位置:char*strstr(const char *s1,const char *s2)
    • 寻找字符串第一次出现的位置(忽略大小写):char* strcasestr(const char *s1,const char *s2)

参考:C语言程序设计(浙江大学):https://www.bilibili.com/video/av15267247
iwehdio的博客园:https://www.cnblogs.com/iwehdio/
原文地址:https://www.cnblogs.com/iwehdio/p/12447813.html