C语言的字符串及其相关函数

一、字符串

1.字符串介绍

  • 以 整数0 或者 ‘\0’ 结尾的一串字符。
  • string.h里面有很多处理字符串的函数。
  • 0标志字符串的结束,但它不是字符串的一部分,即计算字符串长度不包含这个0,
    • 但是如果以’\0’结束,它是属于字符串的一部分。
  • 字符串是以数组的形式存在:
    • 以数组或指针的形式访问; 通过数组的方式可以遍历字符串;
    • 不能用运算符对字符串做运算;
  • 字符串会自动将两个相邻的字符串合并:
    • printf(“hello, i am first line.”
      “Here is the second line of automatic connection.”)
  • 唯一特殊的地方是字符串字面量可以用来初始化字符数组。

2.字符串变量

char *str = "hello";        有一个指针指向hello
char word[] = "hello";
char line[10] = "hello";

"hello"会被编译器变成一个字符数组放在某处,这个数组的长度是6,
结尾还有表示结束的0。

3.字符串常量

char* s = "hello world";

  • s是一个指针,初始化为指向一个字符串常量。
    • 由于这个常量所在的地方是只读的,所以实际上s是const char* s;
    • 但是由于历史原因,编译器接受不带const的写法;
    • 但是试图对s所指的字符串做写入会导致严重的后果。
  • 如果需要修改字符串应该使用数组:
    • char s[] = "hello world";

4.指针还是数组?

  • char *str = “hello”;
  • char word[] = “hello”;
  • 数组: 这个字符串在这里
    • 作为本地变量,空间自动被回收。
  • 指针: 这个字符串不知道在哪里
    • 用于处理参数。
    • 用在动态分配空间的时候。

5.char*是字符串?

  • 字符串可以表达为char*的形式。
  • char*不一定都是字符串。
    • 本意是指向字符的指针,可能指向的是字符数组(像int*一样)。
    • 只有它所指的字符数组有结尾的0时,才能说是字符串。

6.字符串的赋值?(改变指针)

char *t = "title";
char *s;
s = t;

并没有产生新的字符串,只是将指针s指向了t所指的字符串,
对s的任何操作就是对t做的。真正的赋值需使用字符串函数。

7.字符串的输入输出

char string[9];
scanf("%s", string);
printf("%s", string);
  • scanf读入一个单词(到空格、tab或回车为止)
  • scnaf是不安全的,因为不知道要读入的内容的长度。
  • 使用scnaf("%7s",str)表示最多读入7个元素。

8.常见错误

8.1 未初始化
char *string;
scanf("%s", string);
    以为char*是字符串类型,定义了一个字符串类型的变量string就可以直接使用啦,
    由于没有对string初始化为0,所以不一定每次运行都出错。
8.2 空字符串
char buffer[100] = "";
    这是一个空的字符串,buffer[0] == '\0'。
char buffer[] = "";
    这个数组的长度是1,且内容为0。

9.字符串数组

char **a
    a是一个指针,指向另一个指针,那个指针指向一个字符(串)。
char a[][10]
    每一个a[0]都被分为10个字符,里面写着hello,即10个位置没用完。
char *a[]
    这种情况下a[0]相当于char*,a[0]是个指针,指向外面写着hello的某处。

10.程序参数

int main(int argc, char const *argv[])
    argv[0]是命令本身,当使用Unix的符号链接时,反映符号链接的名字。

二、字符串函数

1.单字符的输入输出

putchar
    int putchar(int c);
    向标准输出写一个字符
    返回写了几个字符,EOF(-1)表示写失败

getchar
    int getchar(void);
    从标准输入读入一个字符
    返回类型是int,是为了返回EOF(-1)
        Windows->Ctrl-Z     Unix->Ctrl-D
int main(int argc, char const *argv[])
{
    int ch;
    while((ch = getchar()) != EOF){
        putchar(ch);
    }
    printf("EOF\n");
    return 0;
}

2.函数strlen

size_t strlen(const char *s);
返回s的字符串长度(不包括结尾的0)
char line[] = "hello";
printf("strlen=%lu\n", strlen(line));   //5 长度
printf("sizeof=%lu\n", sizeof(line));   //6 包括字符串特定的结尾0

3.函数strcmp

用来比较字符串,是区分大小写的。字符串大小按照ASCII码表上的顺序决定。
两个字符串相等时返回0;不相等时返回相减的差值。
char s1[] = "abc";
char s2[] = "abc";
char s3[] = "bbc";
printf("%d\n", s1==s2);     //数组这样比较永远都是false
printf("%d\n", strcmp(s1,s2));  //相同大小时返回0
printf("%d\n", strcmp(s1,s3));  //不同时返回s1-s3的差值

4.函数strcpy

char* strcpy(char *restrict dst, const char *restrict src);
把src的字符串拷贝到dst,restrict表明src和dst不重叠(C99)。
会返回dst。(结果不需要赋值)
#include <stdlib.h>
char *dst = (char)malloc(strlen(src)+1);
    //+1不要忘记,否则字符串最后的'\0'就没有空间存放啦
strcpy(dst,src);

5.函数strcat

char* strcat(char *restirct s1, const char *restrict s2);
把s2拷贝到s1的后面,拼接成一个长的字符串。
会返回s1。(结果不需要赋值)  s1必须就有足够的空间。
char s1[] = "hello";
char s2[] = "world";
strcat(s1, s2);
printf("res = %s\n", s1);

6.安全问题

strcpy和strcat都可能出现安全问题,即如果目的地没有足够的空间怎末办?
安全版本:
> 参数 size_t n 即告诉你最多可以放入几个元素。
    char* strncpy(char *restrict dst, const char *restrict src, size_t n);
    char* strncat(char *restrict s1, const char *restrict s2, size_t n);
> 参数 size_t n 即告诉你仅判断前n个字符是否相同。
    int strncmp(const char *s1, const char *s2, size_t n);

7.字符串搜索函数

7.1 字符串中找字符
① char* strchr(const char *str, int c);
        在str中从左往右查找c第一次出现的位置,返回指针;
② char* strrchr(const char *str, int c);
        这个strrchr为从右往左查找;
③返回NULL表示没有找到。
④找到那个字符则返回它以及他后面的所有字符。
7.2 如何寻找第二个字符呢?
char s[] = "hello";
char *p = strchr(s, 'l');   //找到第一个'l'及其后的内容
p = strchr(p+1, 'l');   //找到第二个'l'及其后的内容
printf("%s\n", p);
7.3 将指定字符及其后内容复制到另外一个字符串里
char s[] = "hello_copy";
char *p = strchr(s, 'l');      //查找到第一个'l'
p = strchr(p+1, 'l');   //查找到第二个'l'
char *tmp = (char*)malloc(strlen(p)+1);    //分配p那么多的空间,再加一个'\0'的空间
strcpy(tmp, p);     //拷贝函数
printf("%s\n", tmp);
free(tmp);      //释放空间
7.4 找到指定字符,但是返回其前面部分的内容
char s[] = "hello";
char *p = strchr(s, 'l');
char c = *p;    //将指针位置存放,这样后面还可以复原s字符串
*p = '\0';  //将'l'的位置变为'\0',即将前面部分分割为一个新字符串
char *t = (char*)malloc(strlen(s)+1);
strcpy(t, s);
printf("t=%s, s=%s\n",t,s);
free(t);
*p = c;
printf("s=%s\n",s);
7.5 字符串中找字符串
① char* strstr(const char *s1, const char *s2);
        这个是寻找字符串的。
② char* strcasestr(const char *s1, const char *s2);
        在寻找过程中忽略大小写。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hao难懂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值