字符串

字符数组初始化方法

int main()
{	
	//1 大{}号法 初始化列表
	//数组初始化有2种方法 默认元素个数、指定元素个数
	char buf1[] = {'a', 'b', 'c', 'd', 'e'};	//若没有指定长度,默认不分配零
	//若指定长度,不够报错;buf长度多于初始化个数,会自动补充零
	char buf2[6] = {'a', 'b', 'c', 'd', 'e'};
	char buf3[6] = {'a', 'b', 'c', 'd', 'e'};
	//char buf4[5] = {'a', 'b', 'c', 'd', 'e'};
	printf("buf3:%s", buf3);
	system("pause");
}

在C语言中使用字符数组来模拟字符串
C语言中的字符串是以’\0’结束的字符数组
C语言中的字符串可以分配于栈空间,堆空间或者只读存储区

{
	//1 用字符串来初始化数组
	char buf2[] = {'a', 'b','c','d','\0'};
	//2 字符串常量初始化一个字符数组
	char buf3[] = {"abcde"};	//结论:会补充零
	char buf4[] = "abcde";
	char buf5[100] = "abcde";  

	printf(" strlen(buf5) :%d \n", strlen(buf5));
	printf(" sizeof(buf4) :%d \n", sizeof(buf5));
	printf(" sizeof(buf4) :%d \n", sizeof(buf4));
}

sizeof与strlen的区别

strlen()求字符串的长度,注意字符串的长度不包含\0
sizeof(类型)字符串类型,的大小,包括\0;

数组法和指针法操作字符串

字符数组名,是个指针,是个常量指针;
字符数组名,代表字符数组首元素的地址,不代表整个数组的。
如果代表这个数组,那需要数组数据类型的知识!

//字符串操作方法 数组下标法 指针法
int main()
{
	int i = 0;
	char buf5[100] = "abcde";
	char *p = NULL;

	//下标法
	for (i=0; i<100; i++)
	{
		printf("%c", buf5[i]);
	}
	printf("\n");

	//指针法1
	for (i=0; i<100; i++)
	{		
        printf("%c", *(buf5+i));
	}
	//buf5是个指针,是个常量指针

	//指针法2
	printf("\n");
	p = buf5;
	for (i=0; i<100; i++)
	{
		printf("%c", *(p+i));
	}
	//buf5是个指针,是个常量指针
}

推演过程为:i变0+I, 去[]号加*号
其实本质:指针*p间接寻址,操作内存;
[] 编译器为我们做了*p操作而已

字符串做函数参数

深入理解指针的关键是什么?
一维字符串内存模型:两种

void main()
{
	char buf[20]= "aaaa"; //定义并且初始化
	char buf2[] = "bbbb";
	char *p1 = "111111";
	char *p2 = malloc(100); 
	strcpy(p2, "3333");

	system("pause");
	return ;
}

指针变量可以指向字符常量,但是它所指向内存空间的值不可以修改
指针变量保存着字符常量所在内存空间的地址,所以指针变量可以修改,但是指针变量所指向的内存空间的值不可修改

//*from是指针变量可以被修改,但是它指向的内存空间的值是字符常量,不能被修改
//*to也是指针变量,要想修改它指向的内存空间的值,必须在定义时分配内存空间,并且不能用字符常量初始化
void copy_str01(char *from, char *to)
{
	for (; *from!='\0'; from++, to++)
	{
		*to = *from;
	}
	*to = '\0';
}

void copy_str02(char *from, char *to)
{
	while(*from!='\0')
	{
		*to++ = *from++;
	}
	*to = '\0';
}

void copy_str03(char *from, char *to)
{
	while( (*to=*from) !='\0')
	{
		to++; 
		from++;
	}
}

void copy_str04(char *from, char *to)
{
	while( (*to++=*from++) !='\0')
	{
		;
	}
}

int copy_str05_good(const char *from, char *to)
{
	if (from==NULL || to==NULL)
	{
		printf("func copy_str05_good() err. (from==NULL || to==NULL)\n");
		return -1;
	}

	while( (*to++=*from++) !='\0')
	{
		;
	}
	return 0;
}

//不要轻易改变形参的值, 要引入一个辅助的指针变量. 把形参给接过来.....
int copy_str26_good(char *from , char *to)
{
	char *tmpfrom = from;
	char *tmpto = to;
	if ( from == NULL || to == NULL)
	{
		return -1;
	}

	while ( *tmpto++ = *tmpfrom++ ) ;  //空语句
	printf("from:%s \n", from);
		
}

int main()
{
	int ret = 0;
	char *from = "abcd";
	char buf2[100]; 
	copy_str21(from, buf2);
	copy_str22(from,buf2);
	copy_str23(from, buf2);
	copy_str24(from, buf2);
	copy_str25(from ,buf2);
    //在被调用函数中输出buf2的正确做法
    copy_str26_good(from ,buf2);
    //这里输出buf2没有任何问题,那么,如何在被调用函数里输出buf2?
	printf("buf2:%s \n", buf2);
}

典型错误知多少

char *str_cnct(char *x, char* y)     /*简化算法*/
{
	char str3[80];
	char *z=str3; 	/*指针z指向数组str3*/ 
	while(*z++=*x++);
	z--;	               /*去掉串尾结束标志*/
	while(*z++=*y++);
	z=str3;		 /*将str3地址赋给指针变量z*/
	return(z);
}

修改字符常量结果会如何
Char *p = “abcdefg”;
Modify p[1] = ‘1’;

字符串操作易错

//你往哪里输入数据
int main()
{
	char buf[2000];
	char *p = NULL;//NULL是字符常量
	p  = buf;
	printf("\n请输入一个字符串:");
	scanf("%s", p);
	printf("%s", p);

	getchar();
	getchar();
	return 0;
}

库函数api

快速的上手api是一种能力!

int main00()
{
	char buf1[100];
	char buf2[200];
	strcpy(buf1, "111");
	printf("%s", strcat(buf1, "222"));
	getchar();
	return 0;
}

int main01()
{
	char *string1 = "1234567890";
	char *string2 = "747DC8";
	int length;
	//在字符str1中查找,与str2中任意字符有公共交集的位置
	length = strcspn(string1, string2);
	printf("Character where strings intersect is at position %d\n", length);
	getchar();
	return 0;
}

//strnset函数有错误
//测试程序修改如下
int main02()
{
	char string[] = "abcdefghijklmnopqrstuvwxyz";
	char letter = 'x';
	printf("string before strnset: %s\n", string);
	strnset(string, letter, 13);
	printf("string after  strnset: %s\n", string);
	getchar();
	return 0;
}

int main03()
{
	char *string1 = "abcdefghijklmnopqrstuvwxyz";
	char *string2 = "onm";
	char *ptr;
	ptr = strpbrk(string1, string2);
	if (ptr)
		printf("strpbrk found first character: %c\n", *ptr);
	else
		printf("strpbrk didn't find character in set\n");
	getchar();
	return 0;
}

int main04()
{
   char input[16] = "abc,d";
   char *p;
   /* strtok places a NULL terminator
   in front of the token, if found */
   p = strtok(input, ",");
   if (p)   printf("%s\n", p);
   /* A second call to strtok using a NULL
   as the first parameter returns a pointer
   to the character following the token  */
   p = strtok(NULL, ",");
   if (p)   printf("%s\n", p);

	getchar();
	return 0;
}

//典型的状态函数
int main()
{
	char str[] = "now # is the time for all # good men to come to the # aid of their country";
	//char delims[] = "#";
	char *delims = "#";
	char *result = NULL;
	result = strtok( str, delims );
	while( result != NULL ) {
		printf( "result is \"%s\"\n", result );
		result = strtok( NULL, delims );
	}
	printf("----------==========----------\n");
	printf("%s", str);
	getchar();
	return 0;
}

代码解析 

//一级指针的典型用法
//数组 int a[10]
//字符串 
//1 C语言的字符串 以零结尾的字符串
//2 在C语言中没有字符串类型  通过字符数组 来模拟字符串 
//3 字符串的内存分配  堆上 栈上 全局区 (很重要)

//字符数组 初始化
void main00()
{
	//1 指定长度  
	char buf2[100] = {'a', 'b', 'c', 'd'};  
	//1-1char buf3[2] = {'a', 'b', 'c', 'd'}; //如果初始化的个数大于内存的个数 编译错误
	//1-22//后面的buf2[4]-buf2[99] 0

	//2 不指定长度  C编译器会自动帮程序员 求元素的个数
	char buf1[] = {'a', 'b', 'c', 'd'};  //buf1是一个数组 不是一个以0结尾的字符串
	printf("buf2: %s \n", buf2);
	printf("buf2[88]:%d \n", buf2[88]);
	printf("hello....\n");
	system("pause");
	return ;
}

//用字符串 来 初始化字符数组
//strlen() 长度 不包括0
//sizeof() 内存块的大小
void main01()
{
	int size = 0;
	char buf3[] = "abcd"; // buf3 作为字符数组 应该是5个字节 //作为字符串 应该4个字节

	int len = strlen(buf3);
	printf("buf3字符的长度:%d \n", len); //4

	//buf3 作为数组 数组是一种数据类型 本质(固定小大内存块的别名)
	size = sizeof(buf3); //
	printf("buf3数组所占内存空间大小:%d \n", size); //5
	printf("hello....\n");

	{
		char buf4[128] = "abcd"; // buf
		printf("buf4[100]:%d \n", buf4[100]);
	}
	system("pause");
	return ;
}

//通过数组下标 和 指针
void main02()
{
	int		i = 0;
	char	*p = NULL;
	char buf5[128] = "abcdefg";
    //buf5是一个数组可以用下表取值
	for (i=0; i buf5[0+i]; ==> *(buf5+i);
	{
		//buf5 = buf5 + 1;
		//buf5 = 0x11;
	}
	printf("hello....\n");
	system("pause");
}

// buf[]的本质 :和*p 是一样 ,只不过是符合程序员的阅读习惯
// buf 是一个指针,  只读的常量  buf5是一个常量指针  析构内存的时候,保证buf所指向的内存空间安全释放

 项目开发字符串模型--strstr-whiledowhile模型

//char *p = "abcd111122abcd3333322abcd3333322qqq"; 
//求字符串p中 abcd出现的次数
//1请自定义函数接口,完成上述需求 50 // i++ ++ ++
//2自定义的业务函数 和 main函数必须分开  50

void main00()
{
	//strstr(str, str2)
	int ncount = 0;
	//初始化 让p指针达到查找的条件
	char *p = "11abcd111122abcd3333322abcd3333322qqq";  

	do 
	{
		p = strstr(p, "abcd");
		if (p != NULL)
		{
			ncount++; //
			p = p + strlen("abcd"); //指针达到下次查找的条件
		}
		else
		{
			break;
		}
	} while (*p != '\0');

	printf("ncount:%d \n", ncount);
	system("pause");
	return ;
}

void main01()
{
	int ncount = 0;
	//初始化 让p指针达到查找的条件
	char *p = "2abcd3333322qqqabcd";  
	while ( p = strstr(p, "abcd"))
	{
		ncount ++;
		p = p + strlen("abcd"); //让p指针达到查找的条件
		if (*p == '\0')
		{
			break;
		}
	}
	printf("ncount:%d \n", ncount);

	printf("hello...\n");
	system("pause");
}

//char *p = "abcd111122abcd3333322abcd3333322qqq"; 
//求字符串p中 abcd出现的次数
//1请自定义函数接口,完成上述需求 50 // i++ ++ ++
//2 自定义的业务函数 和 main函数必须分开  50
int getCount(char *mystr /*in*/, char *sub /*in*/,int *ncount)
{
	int ret = 0;
	int tmpCount = 0;
	//初始化 让p指针达到查找的条件
	char *p = mystr; //不要轻易改变形参的值

	if (mystr==NULL || sub==NULL ||ncount==NULL)
	{
		ret = -1;
		printf("func getCount() err:%d (mystr==NULL || sub==NULL ||ncount==NULL) \n", ret);
		return ret;
	}

	do 
	{
		p = strstr(p, sub);
		if (p != NULL)
		{
			tmpCount++; //
			p = p + strlen(sub); //指针达到下次查找的条件
		}
		else
		{
			break;
		}
	} while (*p != '\0');

	*ncount = tmpCount; //间接赋值是指针存在的最大意义
	return ret;
}

int main03()
{
	int ret = 0;
	char *p = "abcd111122abcd3333322abcd3333322qqq"; 
	int count = 0;
	char sub[] = "abcd";

	ret = getCount(p,sub,  &count);
	if (ret != 0)
	{
		printf("func getCount() err:%d \n", ret);
		return ret;
	}

	ret = getCount(p,NULL,  &count);
	if (ret != 0)
	{
		printf("func getCount() err:%d \n", ret);
		return ret;
	}
	printf("count:%d \n", count);
	system("pause");
}

 

 

你可能感兴趣的:(c/c++)