20240321, 字符串操作,STRING.H,字符串函数的实现

啥意思,这个循环是?每次给P分配一个字节,然后把那个位置写入0?但是0是整数吧?他需要四个字节???这和0地址有什么关系……啊啊啊啊啊

 一,字符串操作

1.0 字符数组  补

0标志字符串的结束,但它不是字符串的一部分
计算字符串长度的时候不包含这个0字符串以数组的形式存在,以数组或指针的形式访问更多的是以指针的形式
string.h里有很多处理字符串的函数

	//字符数组
	char word[] = { 'h','e','l','l','o', };
	//字符串
	char w[] = { 'h','e','l','l','0','\0' };
	
	//字符串就是以0或‘\0'结尾的字符数组,注意‘0’是0字符
	//0表示的是INT 要四个字节,\0一定是一个字节的东西
	char* str = "hello";
	//STR是指针,指向了数组{HELLO}
	char word[] = "hello";
	//字符数组,内容是HELLO
	char line[10] = "hello";
	//十个字符的字符数组,放了5个字符,占6个空间,包括结尾的0
	//字面量表达之后,编译器自动生成的

一定要有结尾的0才是字符串
两串相邻的自动连成一串

	printf("的份额服务"
		"feefwefwevwf\n");
	printf("的份额服务\
		feefwefwevwf\n");
//会把前面回退一起输出,\表示输出没有结束

C语言的字符串是以字符数组的形态存在的
不能用运算符对字符串做运算
通过数组的方式可以遍历字符串
唯一特殊的地方是字符串字面量可以用来初始化字符数组
以及标准库提供了一系列字符串函数

1.1 字符串变量  补

int main(int argc,char const *argv[]) {
	int i = 0;
	char* s = "hello world";
	//s[0] = 'b';错误
	char* s2 = "hello world";

	printf("%s\n", s);
	printf("i=%p\n", &i);
	printf("s=%p\n", s);
	printf("s2=%p\n", s2);
	printf("here,s[0]=%c\n", s[0]);
	//S,S2地址一样,I【本地变量】和S不在一个地方
	//S的地址很小,只读,代码端
	//实际上是CONST CHAR*S

	char s3[]= "hello world";
	printf("s3=%p\n", s3);
	printf("i=%p\n", &i);
	s3[0] = 'b';
	printf("%s\n", s3);
	//可以修改
	return 0;
}

指针还是数组,CHAR* S  CHAR S[  ]
指针——1,反正就是用来输出一下,2,作为函数参数,3,分配动态空间【空间是MALLOC得到的,肯定是指针??】 

1.3 字符串输入输出  补

#include<stdio.h>
int main(int argc,char const *argv[]) {
	
	char word[8];
	char word2[8];
	scanf("%s", word);
	scanf("%s", word2);
	printf("%s##\n%s##\n", word, word2);
	//SV不行,回车和空格都是间隔符,和TAB 
	//越界危险
	
	char aa[8];
	scanf("%7s", aa);
	printf("%s##\n", aa); 
	//最多读7个东西 ,剩下的给下一个%s? 
	return 0;
}

常见错误:1,不初始化指针直接使用,CHAR*STRING,
2, 空字符串,char buttur[]="";=='\0\  ,长度只有1

呵呵,我不知道,并且没看懂顶楼大神的高清图 ,大柳树下,互联网大哥的图

Edge Image Viewer (baidu.com)

1.4 字符串数组

#include<stdio.h>
int main() {
	//cha**a ——》A是一个指针,指向另一个指针,这个指针指向一个字符(串)
	//char a[][]//第二维一定要有确定的值

	//a[0] ——》char[10],此时需要注意每一个字符串的长度
	char a[][10] = {
		"hello",
		"word",
		"weewdfwegweh"//太长了
	};
	return 0;
}
#include<stdio.h>
int main() {
	//a[0]——》char*
	char *a[] = {
		"hello",
		"word",
		"weewdfwegweh"
	};
	return 0;
}

1.2.1 月份 
#include<stdio.h>
int main() {
	char* mouth[] = {
		"januaray",
		"february",
		"march",
		"april",
		"may",
		"june",
		"july",
		"august",
		"september",
		"october",
		"november",
		"december",
	};
	int i = 0;
	scanf_s("%d", &i);
	printf("%s\n", mouth[i - 1]);

	return 0;
}
1.2.2 程序参数

#include<stdio.h>
int main(int argc, char const* argv[]) {
	//两个参数,整数,字符串数组
	//整数告诉我们字符串数组有多大,数组带入函数需要另一个参数告诉大小
	int i;
	for (i = 0; i < argc; i++) {
		printf("%d:%s\n", i, argv[i]);
	}
	//什么?0:.a.out,跟上点东西?会被ARGC ARGV读到
	//第一个函数,就是ARGC的0,就是执行的时候读到的命令的名字
	//或者说输入的可执行文件的名字 
	return 0;
}

 不能说毫不相干,只能说南辕北辙,但是突然发现这个是文件的保存地址……啊啊啊
啊啊啊啊啊啊啊啊啊啊啊啊没懂

1.2.3 BUSY BOX  没懂

……………………搜了扫两眼

1.5 PUTCHAR & GETCHAR

#include<stdio.h>
int main()
{	
	int ch;
	while((ch=getchar())!=EOF){
		putchar(ch); 
	}
	printf("EOF\n");
	return 0;
} 

#include<stdio.h>
int main(int argc, char const* argc[])
//运行不了,会说const char**与int的间接寻址级别不同?
//打错字了而已,char const*argv[]

//putchar会把一个字符输出在标准输出上,但是输入的类型是INT类型
//返回的类型也是INT,成功返回1,失败EOF(宏,值是-1)

//getchar返回从标准输入读到的一个字符,类型也是INT
//通过返回EOF表示标准输入结束了
{
	int ch;
	while ((ch = getchar()) != EOF) {
		putchar(ch);
	}
	//输入一个值,读到的如果不是EOF,输出CH
	printf("EOF\n");
	return 0;
}
//输入ctrl d结束了,但是没有输出EOF,只是强制循环结束,没有正确的让他知道,输入结束了
//继续输入还是可以进入循环,就是?没有进行下一步?
//输入CTRL Z,输入结束了,运行到了下一个语句?
//UNIC?需要输入CTRL D

行编辑,缓冲区,SHELL?大概就是两个命令就是不一样吧

二,字符串函数的实现

STRLEN,返回字符串长度
STRCMP,比较大小
STRCPY,拷贝
STRCAT,连接
STRCHAR,寻找一个字符
STRSTR,寻找一个字符串

2.1 STRLEN   长度

 返回字符串长度

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

//写一个代替STRLEN,遍历字符串,知道读到最后的0,结束
int mylen(const char* s) {
	int idx = 0;
	while (s[idx]!='\0') {
		idx++;
	}
	return idx;//没有就0了哦
}

int main() {
	//strlen size_t strlen(const char*s)
	//返回S的字符串长度(不包括结尾的0(\n),SIZEOF包括
	//传入函数数组和指针是一样的,所以用指针表示了?
	//CONST不希望修改数组,不修改字符串

	char line[] = "hello";
	printf("strlen=%lu\n", strlen(line));
	printf("sizeof=%lu\n", sizeof(line));
	printf("mylen=%lu\n", mylen(line));
//5 6
	return 0;
}

2.2 STRCMP  比较

比较字符串大小
两种思路,数组思路,指针思路,编译器会做优化,可能会差不多?

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

//挨个字符对比,知道都是\0,还是相等,则相等
int mycmp(const char*s1,const char*s2) {
	int idx = 0;
	while (1) {
		if (s1[idx] != s2[idx]) {
			break;
		}
		else if (s1[idx] == '\0') {
			break;
		}
		idx++;//都没有出现,继续下一个比较
	}
	return s1[idx]-s2[idx];//返回差值
}

int mycmp1(const char* s1, const char* s2) {
	int idx = 0;
	while (s1[idx] == s2[idx] && s1[idx] != '\0') {
		idx++;
	}
	return s1[idx] - s2[idx];
}

int mycmp2(const char* s1, const char* s2) {
	while (*s1 == *s2 && *s1 != '\0') {
		*s1++;
		*s2++;
	}//注意是不等于‘/-’
	return *s1 - *s2;
}

int main(int argc,char const *argv[]) {
	char s1[] = "abc";
	char s2[] = "abc";
	printf("%d\n", strcmp(s1,s2));
	//0.相等表示0
	//if (strcmp(s1, s2) == 0) ,注意,相等的结果是0,不能直接作为判断条件
	//S1==S2 这个比较永远FAULT,因为这个比较是他们是否是相同的地址,两个变量的地址永远不相同

	char s3[] = "bbc";
	printf("%d\n", strcmp(s1, s3));
	//-1,S3>S1,比他大,因为A在字母表前面,B在字母表后面,所以A小

	char s4[] = "Abc";
	printf("%d\n", strcmp(s1, s4));
	printf("%d\n", 'a' - 'A');
	printf("%d\n", mycmp(s1, s4));//32
	//男神的是32 32 ,我的是1 32,男神说不相等的时候,给出的是两个的差值??
	//差值就是返回值

	char s5[] = "abc ";
	printf("%d\n", strcmp(s1, s5));
	//-1,男神的是32!!!啊啊啊啊为什么!
	printf("%d\n", mycmp(s1, s5));
	//MYCMP输出的是-32!
	printf("%d\n", mycmp1(s1, s5));
	printf("%d\n", mycmp2(s1, s5));
	return 0;
}

2.3 STRCPY  拷贝

拷贝字符串
编译器会把打码优化,所以不用强求自己一定把代码写成那样子……while (*dst = *src);一个空循环

//char*strcpy(char*restrict dst,const char*restrict src);
// (目的,源)(det,src)
//return dst;再参与其他计算

//char* sdt = (char*)malloc(strlen(src) + 1);
// strcpy(dst,src);
//动态分配,申请一块内存把某个位置的字符串复制过来,
//只包括字符的长度,不包括‘\0’的结尾的长度,还要加一!!!
#include<stdio.h>
#include<string.h>

char* mycpy(char* dst, const char* src) {
	int idx = 0;
	while(src[idx]){
		dst[idx] = src[idx];
		idx++;
	}//=0的时候出循环了,所以0没有写进去
	dst[idx] = '\0';
	return dst;
}
//优化,src[idx]!='\0'——》src[idx]:不是0就进入循环

char* mycpy1(char* dst, const char* src) {
	while (*src != '\0') {
		*dst++ = *src++;
	}
	*dst = '\0';
	return dst;
}

char* mycpy2(char* dst, const char* src) {
	while (*dst = *src)
		;
	* dst = '\0';
	return dst;
}

int main(int argc,char const *argv[]) {

	char s1[] = "bbc";
	char s2[] = "abc";
	strcpy(s1, s2);//用于调用的参数太少?
	printf("%s\n",s1);

	return 0;
}

2.4 STRCHR  查询

//char* strchr(const char*s,int c)
//char* strrchr(const char*s,int c)

//从左边数第一次C出现的位置,返回的时指针
//从右边开始
//返回NULL,没找到,非NALL,找到了
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(int argc,char const *argv[]) {

	char s[] = "hello";
	char* p = strchr(s, 'l');
	printf("%s\n", p);
	//LLO,返回一个指针,把后面的东西当作一个字符串输出,LLO
	
	//找第二个,LO
	p = strchr(p + 1, 'l');
	printf("%s\n", p);

	//找到之后把后面的东西复制出来
	char* t = (char*)malloc(strlen(p) + 1);
	strcpy(t, p);
	printf("%s\n", t);
	free(t);
	
	//输出L之前的东西
	char c=*p;//c=l 
	*p='\0';//找到的第二个L,*p=0;
	char* t1=(char*)malloc(strlen(s)+1);//S所指的字符串就只有HEL了 
	strcpy(t1,s);//拷出来 
	printf("%s\n", t1);
	free(t1);
	*p='l';//不要忘记写回去 
	 
	return 0;
}

char* strchr(const char* s,int c)
// 寻找单个字符
char* strstr(const char* s1,const char* s2)
// 寻找一个字符串
char* strcasestr(const char* s1,const char* s2)
//寻找的时候忽略大小写

2.5 STRCAT  连接  补

天杀的,看到这里才发现不对!!!!我要闹了,我都以为学完要关电脑了!!!原来时MOOC23年的那个C程序设计进阶不全,还得看14年的!啊啊啊啊我说怎么字符串开头就如此生硬,就突然就讲了!!!!
连着字符串的内容都要补!!我要闹了!!!
呵呵呵,笑发财,本小白刚知道字符数组和字符串

我!就!说!今天怎么学的懵懵懂懂的!!!啊啊啊啊

#include<stdio.h>
#include<string.h> 
int mycat(char*a,const char*b){
	int i=0;
	for(i=0;a[i]!='\0';i++)
	;
	int t=0;
	for(t=0;a[t]!='\0';t++)
	;
	int s=0;
	for(s=0;s<=t;s++){
		a[i]=b[s];
		s++;
		i++;
	}
	return *a;
} 
int main(int argc, char const* argv[]) {
	//char* strcat(char*restrict s1,const char*restrict s2);
	//把S2拷贝到S1的后面 
	//S1必须有足够的空间 
	char a[]="halllo  ";
	char b[]="byebye";
	strcat(a,b);
	printf("%s\n",a);
	mycat(a,b);
	printf("%s\n",a);
	return 0;
}

STRCPY和STRCAT都有安全问题,空间不足!

char* strncpy(char* restrict dst, cosnt 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);

能够CPY,CAT多少字符,多了就掐掉
对于CMP是,只比较前面N个字符

结束!!!我真的麻了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值