字符串

字符数组

char word[] = { 'H','e','l','l','o','!'};

字符数组不是C语言的字符串,因为不能用字符串的方式做计算

字符串

char word[] = { 'H','e','l','l','o','!','\0' };
int i;
int len = sizeof(word) / sizeof(char);
//len 为数组的长度
for (i = 0; i < len; i++){
	printf("word[%d]=%c\n", i, word[i]);
}
//通过数组的方式可以遍历字符串
运行结果如下:
word[0]=H
word[1]=e
word[2]=l
word[3]=l
word[4]=o
word[5]=!
word[6]=

C语言的字符串是以字符数组的形态存在的,不同于字符数组,它是以0(整数0)结尾的一串字符

  • 0或’\0’是一样的,但是和’0’不同。
  • 0是标志字符串的结束,但它不属于字符串的一部分
  • 计算字符串长度的时候不包含这个0
  • 字符串以数组的形式存在,以数组或指针(更多情况下)的形式访问
  • 相邻的字符串常量会被自动连接起来
  • 不能通过运算符对字符串做运算 (与python相比较)
  • 唯一特殊的地方就是字符串字面量可以用来初始化字符数组
    以及string.h标准库提供了一系列处理字符串的函数

字符串变量

以下都是字符数组变量,但是具有不同的表现形式

char *str = "hello";

此时我有一个名叫str的指针,它指向了一个字符数组 hello
至于这个hello在哪里呢,先不告诉你

char word[] = "hello";

有一个字符数组,里面放着hello

char line[10] = "hello";

字符数组有10个字节,往里面放了一个hello (5个字符占6个字节)
这个数组的长度是6,结尾还有表示结束的0

字符串常量

	char* s1 = "hello";  
    //s1是一个指针,初始化为指向一个字符串常量 
    //s[0] = 'B'; error
    等同于 const char *s;
    //只能读 不能改
    char* s2 = "hello";
    int i; //i为本地变量
    printf("s1=%p\n", s1);
    printf("s2=%p\n", s2);
	printf("&i=%p\n", &i);
运行结果
	s1=004A7B30
	s2=004A7B30  //指向相同字符串字符量的指针被赋予相同的值
	&i=00EFF990  //s所指向得字符串离这个i的值离得很远
  	//被放在代码段不可修改 在很远的地方 只读

如果要对字符串进行修改,应该用数组构造字符串

  char s3[] = "hello";  
  //数组形式可以修改字符串 在本地变量里
  编译器会把放在不可读的 hello 拷贝一份
  printf(("s3=%p\n", s3);
	s3[1] = 'B' //可以改变
运行结果
	s1=009C7B30
	s2=009C7B30
	&i=00CFF870
	s3=00CFF860 
//s3也是一个很大的值 在本地变量中

指针还是数组?

数组形式: 这个字符串在这里

  • 作为本地变量空间自动被回收

指针形式: 这个字符串不知道在哪里

  • 处理参数
  • 动态分配空间

如果要构造一个字符串—>数组
如果要处理一个字符串—>指针

char *是字符串吗?

  • 字符串可以表示为 char* 的形式
  • char* 不一定是字符串
  • 本意是指向字符的指针,也可能是指向的是 字符的数组
  • 只有当它所指的字符数组有结尾的0时,才能说它所指的是字符串

字符串赋值

char *t = "title";
char *s;
s=t
  • 这个代码并没有产生新的字符串
    t所指的字符串,对s任何操作就是对t做的

字符串输入输出

char string[8];
scanf("%s", string);
printf("%s", string); //%s读单词

scanf 读入一个单词(到tab/blankspace/enter为止)
不知道读入的内容的长度,scanf是不安全的

安全输入

char string[8];
scanf("%7s",string);
//这个数字应该比数组长度小1

下一次读接着读直到()停

野指针

char *string;  //不直接是字符串类型,它只是定义的一个指针,指向某一个字符串
scanf("%s",string);
//没有对string初始化为0,所以不一定每一次运行都出错

空字符串

char buffer[100] = '''';
这是一个空的字符串 buffer[0] == '\0' 有效
char buffer[] = '''';
希望编译器去决定字符串的长度
这个数组的长度只有1

字符串数组

char **a;

a是一个指针,指向另一个指针,那个指针指向一个字符串
char a[][]
第二维有要确切的值

char a[][10] = {
		"hello",
		"world",
		"helloworld "  //数组界限溢出
	};

程序参数

//一个整数 一个字符串 整数告诉我们字符串有多大
int main(int argc, char const *argv[])
		//argv[0]是命令本身
{
 int i;
 for ( i=0; i<argc; i++ ){
 	printf("%d:%s\n", i, argv[i]);
 	}
 	return 0;
} 	

单字符的输入输出

int putchar(int c)
向标准输出写一个字符
返回写了几个字符
返回错误: EOF(-1)表示写失败
end of file 文件结束
int getchar(void)
从标准输入读入一个字符
返回类型是int是为了返回EOF(-1)

int main(int argc, char const* argv[])
//argv[0]是命令本身
{
    int ch;
    while ((ch = getchar()) != EOF) {
        putchar(ch);
    }
    printf("over")
    return 0;
}

CTRL+Z退出循环 CTRL+C退出程序

string.h

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

strlen length
size_t strlen(const char *s)
const保证strlen不会改变s

    char line[] = "hello";
    printf("strlen=%d\n", strlen(line));
    printf("sizeof=%d\n", sizeof(line));
    return 0;
strlen=5
sizeof=6 //多一个'\0'

自己定义strlen函数

int mylen(const char* s) {
    int idx = 0;
    while (s[idx]!='\0') {
        idx++;
    }
    return idx;
}

strcmp compare
int strcom(const char*s1, const char *s2)
返回值:
0 : s1==s2
1 : s1 > s2
-1:s1 < s2

    char s1[] = "abc";
    char s2[] = "abc";
    printf("%d\n", s1 == s2);
//== 比较的是两个字符串的地址是否一样
//地址当然不同,所以结果都是false
    printf("%d\n", strcmp(s1, s2));
	0
	0

自行定义strcmp函数

  • 数组
int mystrcmp(const char* s1, const char* s2) {
    int idx = 0;
    int ret = 0;
    while (s1[idx]==s2[idx]&&s1[idx]!='\0') {
        idx++;
    }
    if (s1[idx] - s2[idx] == 0) {
        ret = 0;
    }
    else if (s1[idx] - s2[idx] < 0) {
        ret = -1;
    }
    else {
        ret = 1;
    }
    return ret;
}
  • 指针
int mystrcmp(const char* s1, const char* s2) {
    int idx = 0;
    int ret = 0;
    while (*s1 == *s2 && *s1!= '\0') {
        s1++;
        s2++;
    }
    if (*s1 - *s2 == 0) {
        ret = 0;
    }
    else if (*s1 - *s2 < 0) {
        ret = -1;
    }
    else {
        ret = 1;
    }
    return ret;
}

strcpy copy
char*t strcpy(char *restrict dst,const char *restrict src)
把src的字符串拷贝到dst
src:srouce
dst:destination

  • restrict表明src和dst不重叠
  • 返回dst
  • 为了能链起代码来
char* dst = (char*)malloc(strlen(src) + 1);
strcpy(dst,src);
  • 数组
char* mycpy(char* dst, const char* src) {
	int idx = 0;
while (src[idx]) {
	dst[idx] = scr[idx];
	idx++;
}
dst[idx] = '\0';
return dst;
  • 指针
char* mycpy(char* dst, const char* src) {
	char *ret = dst;
	while (*src) {
		*dst++ = *src++;
	}
	*dst = '\0';
	return ret;
}
char* mycpy(char* dst, const char* src) {
	char *ret = dst;
	while (*dst++ = *src**)
	;
	/*空的循环*/
	*dst = '\0';
	return ret;
}

strcat catenate 连接
char * stract(char*restrict s1, const char *restrict s2);

  • 把s2拷贝到s1的后面,接成一个长的字符串
  • 返回s1
  • s1必须拥有足够的空间

与copy相类似

  • strcpy dst[0]
  • strcat dst[strlen(dst)]

安全问题

  • dst没有足够的空间

安全版本

  • char*t strncpy(char *restrict dst,const char *restrict src, size_t n);
  • charstract(charrestrict s1, const char *restrict s2, size_t n);
  • int strncmp(const char*s1, const char *s2, size_t n);
    //比较前几个字符是不是相同,就没有必要考虑后面的字符,故可以用n来限制长度

字符串搜索函数

字符串中找字符
char * strchr (const char *s, int c);
//从左边找过来
char * strrchr (const char *s, int c);
//从右边找过来
返回NULL表示没有找到

int main() {
	char s[] = "hello";
	char* p = strchr(s, 'l');
	printf("%s\n", p);

	p = strchr(p + 1, 'l');
	printf("%s\n", p);

	return 0;
}
int main() {
	char s[] = "hello";
	char* p = strchr(s, 'l');
	char c = *p;
	*p = '\0';
	char* t = (char*)malloc(strlen(p) + 1);
	strcpy(t, s);
	printf("%s\n", t);
	free(t);
	return 0;
}

字符串中找字符串
char * strstr (const char s1, const chars2);
char * strcasestr (const char s1, const chars2);
//忽略字母大小写

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值