17-字符串

字符数组

  • char word[ ] = { ‘H’ , ‘e’, ‘l’ , ‘l’ , ‘o’ , ‘!’};
    请添加图片描述

字符串

  • char word[ ] = {‘H’ , ‘e’, ‘l’ , ‘l’ , ‘o’ , ‘!’ , ‘\0’};
    请添加图片描述

  • 以0 (整数0)结尾的一串字符

  • 0或\0’’是一样的,但是和’0’不同

  • 0标志字符串的结束,但它不是字符串的一部分

  • 计算字符串长度的时候不包含这个0

  • 字符串以数组的形式存在,以数组或指针的形式访问

  • 更多的是以指针的形式
    string.h 里有很多处理字符串的函数

字符串变量

  • char *str == “Hello”;
  • char word[ ] = “Hello”;
  • char line[ ] = “Hello”;
    "Hello"是字符串常量,它会被编译器变成一个字符数组放在某处,这个数组的长度是6(结尾还有一个表示结束的0)
  • 两个相邻的字符串常量会被自动连接起来
  • c语言的字符是以字符数组的形态存在的
    不能用运算符对字符串做运算
    可以通过数组的方式遍历字符串
  • 唯一特殊的地方是字符串字面量可以用来初始化字符数组
  • 以及标准库提供了一系列字符串函数

下面对 char *s = “Hello word!”; 进行理解:

  • s是一个指针,初始化为指向一个字符串常量
  • 由于这个常量所在的地方不变,所以实际上s是const char *s,但由于历史原因,编译器接受不带const写法
  • 试图对s所指的字符串做写入会导致严重的后果(如: s [0] = ‘B’; 是错误的)
    原因:char *s = "Hello word!"中指针s指向的地方也就是 "Hello word!"字符常量的地址,电脑把它的地址分配到了代码区,只能读不能写;若int a[]; char *s = a;,则此时指针s指向的a是本地变量,可以改变
  • 如果要修改字符串,应用数组
    char a[] = “Hello word!”;
    char *s = a;
    *s = ‘b’; //此时输出a为 bello word!

指针还是数组

  • 数组:char word[] = “Hello”;
    这个字符串就在这里,作为本地变量自动被回收

  • 指针:char *s = “Hello”;
    这个字符串不知道在哪里,随机电脑分配
    处理参数,动态分配空间

  • 如果要构造一个字符串 —>用数组形式

  • 如果要处理一个字符串 —>用指针形式

关于char*

  • 字符串可以表达为char*的形式

  • char*不一 定是字符串

  • 本意是指向字符的指针,可能指向的是字符 的数组(就像int*一样)

  • 只有它所指的字符数组有结尾的0,才能说它所指的是字符串

字符串赋值

char *t = “title”;
char *s;
s = t;
这里并没有产生新的字符串,只是让指针s指向了t所指的字符串,实际上s中存放值的也是那个字符串的地址,对s的任何操作就是对t做的

字符串输入输出

char string[8];
scanf(“%s”,string);
printf(“%s”,string);

  • scanf读入一个单词(到空格,tab或回车为止)
    scanf是不安全的,因为不知道要读入内容的长度
  • 安全的输入:
    char string[8];
    scanf(“%7s”,string);
    注:在%和s之间的数字表示最多允许读入的字符的数量,这个数字的大小应该比数组的大小小一
    此时下一次scanf从接下来的单词阅读,直到读到下一个空格为止(当然要小于数组的长度)
    看一个例子:
#include <stdio.h>
void f(void)
{
	char word [8];
	char word2[8];
	scanf("%7s", word) ;
	scanf ( "%7s", word2);
	printf( "%S##%S##\n", word, word2);
}

int main(void)
{
	f();
	return 0;
}

结果如下:
输入:12345678
输出:1234567##8##

输入:123
12345678
输出:123##1234567##

输入:12345678 98
输出:1234567##8##

字符串常见错误

  • char *string;

  • scanf(“%s", string);

  • 以为char*是字符串类型,定义了一个字符串类型的变量string就可以直接使用了,但由于没有对string初始化为0,所以不一定 每次运行都出错

空字符串

  • char butffer[100] = “”;
    这是一个空字符串,buffer[0] == ‘\0’
  • char buffer[] = “”;
    这个数组的长度只有1(数组中只有表结束的0)

字符串函数

头文件:<string.h>

  1. strlen
    函数原型:int size_t strlen(const char *s);
    返回:s的字符串长度

eg:
char line[] = “Hello”;
printf(“%lu”,strlen(line)); //结果为5

  1. strcmp
    函数原型:int strcmp(const char *s1 , const char *s2);
    比较函数两个字符串.返回:
    0: s1 == s2
    1: s1 > s2
    -1: s1 < s2

eg:
char s1[] = “abc”; //“abc” “abc”
char s2[] = “abc”; //“bbc” “Abc”
printf(“%d\n”,strcmp(s1,s2)); //0, -1 , 32

若在程序中直接写s1 == s2,则结果一定是false,因为这两个数组一定不会是相同的地址

  1. strcpy
    函数原型:char *strcpy(char *restrict dst , const char *restrict src);
    把src的字符串拷贝到dst
    restrist表明src和dst不重叠
    返回:指针dst,让代码连起来
  2. strcat
    函数原型:char *strcat (char *restrict s1 , const char *restrict s2);
    把s2拷贝到s1后面,接成一个长的字符串
    返回:指针s1, (注:s1必须具有足够的空间)

安全问题:strcpy和strcat可能出现安全问题,如果目的地没有足够的空间,会出错

安全版本:
char * strncpy(char *restrict dst, const char *restrict src, size_ _t n);

char * strncat(char *restrict s1, const char *restrict s2, size_ t n);

int strncmp(const char *s1, const char *s2, size_ t n);
(n表示最多能输入的长度)

  1. strchr
    函数原型:char *strchr(const *s , int c);
    (从左边)寻找c在字符串中第一次出现的位置
    返回:指针,指向那个位置
  2. strrchr
    函数原型:char *strrchr(const *s , int c);
    (从右边)寻找c在字符串中第一次出现的位置
    返回:指针,指向那个位置

这两个函数( strchr,strrchr)返回NULL表示没有找到

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值