欢迎来到Cefler的博客😁
🕌博客主页:那个传说中的man的主页
🏠个人专栏:题目解析
🌎推荐文章:题目大解析(更新ing)
题目:
写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
#include <string.h>
int find_str(char* arr, char* arr2)
{
char tmp[24] = { 0 };//创建一个数组存放字符串
strcpy(tmp, arr);//先拷贝
strcat(tmp, arr);//再连接
return strstr(tmp, arr2) != NULL;
}
int main()
{
char arr[] ="ABCDE";
char arr2[20] = { 0 };
//我们要算出这个字符串有多长
int len = strlen(arr);
while (1)
{
printf("原字符串为:%s\n", arr);
aggin:
printf("请输入一串字符:");
scanf("%s", arr2);
//判断下输入的字符串长度是否==len
char* p = arr2;
int len2 = 0;
while (*p != '\0')
{
len2++;
p++;
}
if (len2 != len)
{
printf("你所输入的字符串长度与原字符串长度不相同,请重新输入\a\n");
goto aggin;
}
//此时开始正式创建一个函数判断是否为左右旋转后的字符串
if (find_str(arr, arr2))
{
printf("此字符串为原字符串左/右旋后的字符串\n");
}
else
printf("原字符串左/右旋后得不到该字符串\a\n");
}
return 0;
}
这里涉及到了几个新的知识点
- strcpy:复制字符串
- strcat:连接字符串
- strstr:
1、strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。
2、找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址;
3、如果未找到所搜索的字符串,则返回NULL。
其实这道题还可以再优化。
在我做完这道题发现,对一个arr[n]={0}的字符数组(n已经为定义的常量)
我们scanf(“%s”,&arr)输入一段字符串,这个字符串的长度就是arr的长度了,
因为当你向数组中输入一段字符串后,剩下的元素其实都是’\0’。
由此,可以做什么优化呢?
我们可以自主输入一段字符串作为原字符串
,题目就变得更灵活了。
get和fgets
get:
首先要记住的一句话就是Never use gets().
这是因为gets()函数不检查目标数组是否能够容纳输入,而若想把一个字符串读到程序中,最先要做的事情就是预留存储字符串的空间。所以这很容易导致分配的空间不够大而数组越界,然而gets()函数并不检查这个方面,所以导致的结果就是程序很容易出现漏洞,著名的“蠕虫”病毒的原理就是用很长的数据覆盖原有数据导致崩溃。所以对于重要的编程,永远不要使用gets()!
1, gets()的参数是一个地址,因为要把从键盘输入的值确定的放到某一块内存中,所以需要指定它的地址,而通常使用gets(数组名)这种方式来把输入的字符串传入给定的数组中。注意:这个数组的大小一定要事先定义好!若不将数组的大小定义好,就有可能在输入的时候不知道把字符串输入到哪块内存中去了,就有可能会导致对该内存中原代码的覆盖。
2, gets()的第一个用法:直接用gets(array’s name);这种方式时,由于不知道什么时候才会到字符串结尾,所以每当键入’\n’, gets()函数都会自动读取换行符前面的所有内容并且在末尾加上’\0’,并且直接把这个字符串返回给调用它的程序,然后gets()再进行读取并且会把读取到的’\n’丢弃,这样下一次读取就会在新的一行开始。
注意:现在基本上不使用gets(),可以说它是一个已经被废弃的函数,现在可以用scanf(), getchar(), fgets()来代替它。
fgets:
fgets()(函数原型:char *fgets(char *restrict str, int size, FILE *restrict stream))
(char *fgets(“容器的地址”, “容器的大小”, “从哪里读取”))