scanf("%[^\n],str);和gets(str)
首先,调试环境是VS2017,所以没有gets只有gets_s,所以就只读入一个100个字符的字符串试试吧。
背景
这个问题产生的背景是这样的。我在PTA上刷题的时候产生了一些奇怪的现象,在开始我是以为scanf[]和gets是一样的,后来…我发现事情貌似并不是那么的简单…
题目描述:
提交代码为
#include <stdio.h>
#include <string.h>
int main() {
char str[81] = {};
char c;
int num[127] = {};
scanf("%[^\n]\n%c", str, &c);
int n = strlen(str);
int i;
for (i = 0; i < n; i++) num[str[i]]++;
printf("%d", num[c]);
}
时的结果为
有一个是不通过的,然后提交代码变为下面的时候是通过的
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
//#define gets(A) gets_s(A,81)
int main() {
char str[81] = {};
int num[127] = {};
gets(str);
char c = getchar();
int n = strlen(str);
int i;
for (i = 0; i < n; i++) num[str[i]]++;
printf("%d", num[c]);
}
这是为什么呢?我进行了下面的实验。
测试用的代码如下:
#include <stdio.h>
#include <string.h>
#define gets(A) gets_s(A,100)
inline void input_str(char* str) {
gets(str);
scanf("%[^\n]",str);
}
int main() {
char str[101] = {};
input_str(str);
printf("%s", str);
}
第一次,提交一个没有空格的字符串
gets的效果为:
scanf的效果为:
第二次,提交一个带有一个空格的字符串
gets的效果为:
gets可以成功读入空格。
scanf的效果如下:
也可以成功读取空格
第三次,提交一个带有一个制表符的字符串
gets的效果为:
gets可以成功读取\t
那么,scanf呢?
还是可以正确读取的。
所以…
第三次,组合攻击!!!!!!
gets的效果为:
scanf的效果为:
这他喵难道不一样吗?!?!
自闭了。
那就换个编译器试试?
VC6.0走起!
实验截图就省了吧,就上一张就可以说明问题了
还是不能确定…
Dev-C试一下…
so…是不是系统的问题?
那就换linux试一下吧。
系统:Ubuntu
编译器:GCC
现在GCC没gets,那就用fgets吧…
fgets和gets比会多吃一个回车
测试代码如下:
#include <stdio.h>
int main(){
char str1[81] = {};
char str2[81] = {};
fgets(str1,81,stdin);
scanf("%[^\n]",str2);
getchar();
printf("%s%s",str1,str2);
getchar();
}
好像也是没什么区别的吧…那么为什么不可以呢…有一些奇怪
用Kali试一下…
结果也一样…
所以,两者应该没什么区别吧,大概…
所以,那个代码不可以是因为scanf读取c时的问题,把scanf换成getchar就好。