C语言学习笔记9

字符串练习题

//1.查找一个字符在另外一个字符串中第一次出现的下标
//2.查找一个字符在另外一个字符串中第一次出现的地址
//3.查找一个字符串在另外一个字符串中第一次出现的地址 abcccccde ccd
//4.统计一个字符串中单词的个数(单词与单词之间是空格分割)“a abc make 89 12 a ma make 12 abc 89”
//5.将一个字符串插入到另一个字符串中 “abcd” “12345” 3
//(将第二个字符串插入到第一个字符串第三位的前面也就是ab12345cd)

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

int T1(char* str, char a);
char* T2(char* str, char a);
char* T3(char* str1, char* str2);
int T4(char* str1);
//char* T5(char* str1, char* str2, char* str);
//插入要在原有的基础上去做,不要开辟更大的空间
void T5(char* str1, char* str2, int n);

int main() 
{
	printf("T1----------------------\n");
	printf("%d\n", T1("abc", 'c'));
	printf("%d\n\n", T1("abc", 'e'));

	printf("T2----------------------\n");
	//(检验地址可以间接引用,看看是不是这个地址上的内容就可以了)
	printf("%c\n\n", *T2("abc", 'c'));

	printf("T3----------------------\n");
	//(只要确认前三个内容正确即可)
	printf("%s\n\n", T3("abcccccde", "ccd"));

	printf("T4----------------------\n");
	printf("%d\n\n", T4("a abc make 89 12 a ma make 12 abc 89"));

	printf("T5----------------------\n");
	//printf("%s\n\n",T5("abcd","12345",3));
	//str1的数组长度不够大
	char str[20] = "abcd";
	T5(str, "12345", 3);
	printf("%s\n\n", str);
	//输出结果是ab12345


	return 0;

}

int T1(char* str, char a) 
{
	int Mark = 0;
	while (*str != '\0') 
	{
		if (*str == a) 
		{
			return Mark;
		}
		str++;
		Mark++;
	}
	return -1;
}

char* T2(char* str, char a)
{
	while (*str != '\0')
	{
		if (*str == a)
		{
			return str;
		}
		str++;
	}
	return NULL;
}


char* T3(char* str1, char* str2) 
{
	while (*str1 != '0') 
	{
		if (0 == strncmp(str1, str2, strlen(str2)))
		{
			return str1;
		}
		str1++;//char* 字符指针数据类型,str1++则表示指向位置偏移
	}
	return NULL;
}

int T4(char* str1) 
{
	int count = 0;
	while (*str1 != '\0') 
	{
		if (*str1 == ' ') //注意=和==的区别!
		{
			count++;
		}
		str1++;
	}
	return count+1;
}//注意:本程序只能计算每个单词之间空一个格的单词个数,如果每个单词间空多个或者全是空格没有单词则不成立了

void T5(char* str1, char* str2, int n)
//思路:
//先找到第三位的位置,两种方式,①先遍历字符串找到第三位,②直接进行字符串数组偏移到第三位
//然后再将第三位之后的字符串偏移插入字符串字数的数量,需要注意的是要从后往前一位位移动,如果从前往后以后,一旦第三位之后的字符串字数数量大于要插入的字符串字数数量,那么原来的字符串就会有被覆盖的情况发生。
{
	char* p1 = str1 + n - 1;//找到第三位前的位置:首地址+3-1
	char* p2 = str1 + strlen(str1);//找到'\0'的位置,还有遍历的方法但是比较麻烦
	//strlen计算字符串长度时候不计算’\0’在内,-1的原因是str1是第一个字符的地址,strlen把第一个重复计入了
	//①while (p1 < p2) //要插入的位置在\0的前面
	//但此时c没有挪过去,当p1和p2都指向c时,没有进入循环
	while (p1<=p2)
	{
		*(p2 + strlen(str2)) = *p2;
		//第一次进入循环时的解释//对p2 + strlen(str2)这个地址上的内容进行赋值,所以使用间接引用
							//p2 + strlen(str2)的含义是\0所在的地址往后偏移str2个长度
							//最终达到把\0移动到str2字符串数组长度之后的位置上,以便插入str2这个字符串
		p2--;
	}

	while (*str2 != 0) 
	{
		*p1 = *str2;
		p1++;
		str2++;
	}//①的情况下:为什么c本来应该出现的位置不是空而是\0呢?
	 //主函数中定义char str[20] = "abcd";//不完全初始化,后面没有初始化的部分全部都是'\0'
}

字符串练习题2

//6.翻转字符串
//7.判断是否回文(回文指的是顺读和逆读都一样的字符串) “abcdcba”

void T6(char* str);
int T7(char* str);

int main() 
{
	char str[] = "123456";
	T6(str);
	printf("%s\n", str);
	
	printf("%d\n", T7("123456"));
	printf("%d\n", T7("abcdcba"));

	return 0;
}

void T6(char* str) 
{
	char* begin = str;
	char* end = str + strlen(str) - 1;
	char c;

	while (begin < end)
	{
		c = *begin;
		*begin = *end;
		*end = c;

		begin++;
		end--;
	}
}

int T7(char* str) 
{
	char* begin = str;
	char* end = str + strlen(str) - 1;
	int Bool = 0;

	while (begin < end)
	{
		if (*begin == *end)
		{
			begin++;
			end--;
		}
		if (*begin != *end) 
		{
			return Bool;
		}
	}
	while (begin = end)
	{
		Bool++;
		return Bool;
	}
	return Bool;
}

getchar()

int main()
{
	printf("%c\n", getchar());
	printf("%c\n", getchar());
	printf("%c\n", getchar());
	printf("%c\n", getchar());
	printf("%c\n", getchar());
	//输入字符后可以读取一位
	//输入abc\0,实际上需要读取四位,最后的\0也会被获取,所以再输入ab时只能读取a

	return 0;
}

要求:未知多少位的情况下,需要将所有内容回显出来

int main() 
{
	//while (getchar() != '\n')
	//{
	//	printf("%c", getchar());
	//}

	//以12345\n为例,输出24且无法结束程序
	//getchar() != '\n'中getchar得到135,printf("%c", getchar())中getchar()得到24\n
	//以1234\0为例,输出24后可以结束程序
	//getchar() != '\n'中getchar得到13\n,printf("%c", getchar())中getchar()得到24

	//getchar()每次读取一个字符后无论是否输出都不会存放


	char c;
	//while (c = getchar() != '\n')
	//!=的优先级比=高,因此先执行getchar() != '\n'返回真也就是1
	//所以c(char型)存放的是1,会显示出方块

	while ((c = getchar()) != '\n')
	{
		printf("%c", c);
	}
	return 0;
}

暂存用户输入的一段字符,以便所需时取用

char* GetString();

int main()
{

	char* str = GetString();

	printf("%s\n", str);

	return 0;
}

char* GetString()
{
	char c;
	int size = 5;
	char* str = (char*)malloc(size);
	int count = 0;
	char* newstr = NULL;
	char* pMark = str;

	//从输入缓冲区中取字符
	while ((c = getchar()) != '\n')
	{
		//取下的字符放到字符数组里
		*str = c;
		//计数累计
		count++;
		str++;
		//判断是否能放下
		if (count + 1 == size)
		{
			//放不下
			//变字符串
			*str = '\0';
			//size增大
			size += 5;
			//开辟一个新的空间
			newstr = (char*)malloc(size);
			//将老字符串拷贝到新字符数组中
			strcpy_s(newstr, size, pMark);
			//释放老字符串
			free(pMark);
			//找到新字符串结尾位置
			str = newstr + count;
			//标记指向字符串首地址
			pMark = newstr;
		}
	}
	//变字符串
	*str = '\0';

	return pMark;
}

比较两个字符串:strcmp

//返回值Int类型,参数char*
//返回值为0时,字符串1等于字符串2;为-1时,字符串1小于字符串2;为1时,字符串1大于字符串2
//按位比较而不是比较长度~

//strncmp	比较部分字符串(前几位)

int MYstrcmp2(char* str1, char* str2);
int MYstrcmp(char* str1,char* str2);

int main()
{
	printf("%d\n", MYstrcmp("ac", "abc"));
	printf("%d\n", MYstrcmp("ab", "abc"));
	printf("%d\n", MYstrcmp("abc", "abc"));
	printf("----------------------\n");
	printf("%d\n", strcmp("ac", "abc"));//第二位上,c的ASCII码比b大,因此输出1
	printf("%d\n", strcmp("ab", "abc"));
	printf("%d\n", strcmp("abc", "abc"));
	printf("----------------------\n");
	printf("%d\n", MYstrcmp2("ac", "abc"));//第二位上,c的ASCII码比b大,因此输出1
	printf("%d\n", MYstrcmp2("ab", "abc"));
	printf("%d\n", MYstrcmp2("abc", "abc"));
	printf("----------------------\n");
	printf("%d\n", strncmp("ab", "abc", 2));

	return 0;
}


//strcmp函数的仿写

int MYstrcmp(char* str1,char* str2)
{
	while (*str1!='\0' && *str2!='\0')//只要有一个到'\0'就跳出循环
	{
		if (*str1<*str2)
		{
			return -1;
		}
		else if (*str2<*str1)
		{
			return 1;
		}
		else
		{
			str1++;
			str2++;
		}
	}

		if (*str1 < *str2)
		{
			return -1;
		}
		else if (*str2 < *str1)
		{
			return 1;
		}
		else
		{
			return 0;
		}

}

int MYstrcmp2(char* str1, char* str2) 
{
	while (*str1!='\0'||*str2!='\0')//两个都到'\0'才跳出循环
	{
		if (*str1 < *str2)
		{
			return -1;
		}
		else if (*str2 < *str1)
		{
			return 1;
		}
		else
		{
			str1++;
			str2++;
		}
	}
	return 0;
}

/*思路:
定义一个char类型字符(传入)
用malloc函数在堆区开辟一个新的空间存字符串
定义一个char* 类型指针标记字符串首地址
定义一个char* 类型字符串为空
定义一个int类型变量计数

while循环,当传入字符c不等于‘\n’时
字符c的值传入malloc定义的字符串,
字符串地址后移
计数
当(统计次数 + 1)等于开辟空间大小时
给字符串赋‘\0’
增大空间
给新字符串开辟增大后的空间
调用strcpy函数将原有字符串(标记指针所指向)内容存到新的字符串中
释放原字符串的空间
标记指针指向新字符串的首地址
最后为字符串赋‘\0’
返回 标记指针首地址
*/ 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

97Marcus

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

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

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

打赏作者

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

抵扣说明:

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

余额充值