int main(){ char str[100]; gets(str); getchar(); char ch[100]; gets(ch); int len=strlen(str); int le=strlen(ch); for(int i=0;i<=len-le;i++){ for(int j=0;j<=le-1;j++){ if(str[i+j]!=ch[j]){ break; } if(j==le-1){ printf("%d",i); } } } return 0; }
编译,然后运行(dev c++中先F9然后F10)
我们发现,输出的数据总是比我们期望的多了一个
例如,输入asdfgh和fg,结果输出4而不是3
为什么?问了老师,发现问题出在getchar();
scanf
在读取输入时不会清除输入缓冲区中的换行符(\n
)
fgets读取到\n或者到n个字符为止,gets则是读取到\n
所以,当我们连用scanf+gets/fgets,且以\n结束scanf的输入,那么下面的gets/fgets将读取缓冲区中的换行符。对于fgets,存储的字符为\n\0
,然后退出;对于gets,存储的字符为\0
(也就是啥也没存到),然后退出
//PS:如果是空格+sth+\n结尾,那么scanf留下"空格+sth+\n"在缓冲区,那么下一个fgets/gets也会直接读取缓冲区的内容
#include<stdio.h> #include<string.h> int main(){ char str[100]; char arr[100]; scanf("%s",str); gets(arr); printf("%s\n%s",str,arr); return 0; }
比如我输入asd空格fg回车
结果,str会读取asd,然后后面自动补\0,arr会读取缓冲区的空格fg回车,成为空格fg\0
回到题目,我们在两次使用gets的中间使用getchar();
其实是赘余操作
我理解的是只要没有缓冲区溢出,那么gets的缓冲区应该是啥也没有的
你使用getchar();
其实就是把第二个gets的第一个字符给阻断了,导致第二个gets读取的字符串少了第一个字符,这就是为什么输出的i会不符预期
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> int main() { char str[100]; char st[100]; gets(str); gets(st); int len = strlen(str); int le = strlen(st); int s = 0; for (int i = 0; i <= len - 1; i++) { for (int j = 0; j <= le - 1; j++) { if (str[i + j] != st[j]) { break; } if (j == le - 1) { for (int k = i+le; k <= len - 1; k++) { str[k-le] = str[k]; } s++; } } str[len- (le)*s] = 0; } puts(str); return 0; }
日期:12.25 字符串删除算法,根据这个字符串暴力匹配算法写的
只要找到了要删的字符串,就在if (j == le - 1)
语句里面之间对后面的所有字符进行前移,字符串肯定会变短,所以str[len- (le)*s] = 0;
即可
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> int main() { char str[100]; gets(str); char st[100]; st[0] = str[0]; int len = strlen(str); int index = 0; for (int i = 0; i <= len - 1; i++) { int bz = 0; for (int j = 0; j <= index; j++) { if (str[i] == st[j])bz = 1; } if (bz == 0) { index++; st[index] = str[i]; } } st[++index] = 0; puts(st); return 0; }
日期:12.26 字符串去重算法,要用到"添加标志",同时index++在前,因为我们先让st[0]=str[0]避免没有初始化出现BUG,最后记得添加字符结束符,也就是st[++index] = 0;
Comments NOTHING